[英]c++ operator overloading how to implement the pattern like the ctor of Mat_<type> in opencv
在opencv中,我可以像这样构造Mat的对象:
Mat mat = (Mat_<int>(2, 3) << 1, 2, 3, 4, 5, 6);
所以初始化Mat_<type>
的实例很方便,如果我有一个自定义的简化矩阵类Mat2D
,我将使用这个模式,但怎么办?
更新:我尝试使用变长参数列表,但error C2829: 'operator <<' cannot have a variable parameter list
。
警告:不要这样做。 你被警告了。
你可以使用运算符重载来实现这一点,但这是一个非常糟糕的主意,我稍后会解释。
我假设类Mat
有一个带Mat_<int>
的构造函数。
我假设类模板Mat_<T>
有一个方法Insert()
,它知道如何将单个元素插入到矩阵中。 我会让你解决这个问题,但它需要一种方法来知道在哪里插入它。
使用这种方法很容易重载operator<<
:
template<typename T>
Mat_<T>& operator<<(Mat_<T>& mat, const T& el)
{
mat.Insert(el);
return mat;
}
我们可以重载operator,
来调用这个重载的operator<<
:
template<typename T>
Mat_<T>& operator,(Mat_<T>& mat, const T& el)
{
return mat << el;
}
一切正常,你可以使用你的语法。 现在我将解释为什么这是一个坏主意。
重载operator<<
这种方式是非常明智的。 这是插入操作符,我们的重载将一个元素插入到矩阵中。 这是任何人都期望的; 到现在为止还挺好。
但是重载operator,
不是。 这个运算符的含义是“计算两个表达式,然后返回最后一个”; 这显然不是我们的重载运算符所做的。 粗心的用户会尝试使用运营商,
在标准方式(例如,在for
循环),并会不明白为什么他们的代码不能正常工作。 除非你想被任何使用你代码的人所厌恶,否则你不应该让操作员超负荷进行非标准操作; 可能在某个时候以后。
事实上,虽然标准允许重载operator,
但这是您可能永远不会做的事情,因为编写执行标准操作的代码是不可能的。 您可以认为这是为了向后兼容而保留的标准中的错误。
并且,如果你考虑重载operator,
采用两个int
并以某种方式将它们捆绑在一起,不仅缺点更严重:当所有操作数都是内置类型时,重载操作符是非法的。
总而言之:您可以这样做,但这是一个坏主意,并会在您的代码的意外位置导致错误。
这是使用插入器和逗号运算符作为简单DSL的构建器模式与流畅接口的组合。 我没有看到任何类型的危险(如果正确完成),因为您的DSL定义了这些运算符适用的非常特殊的上下文。 如果您正在寻找灵感,请查看boost :: assign。 无论如何,我使用口头DSL元素而不是运营商,但这仅仅是我个人的偏好......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.