C++ 运算符重载 如何在 OpenCV 中实现像 Mat_ 的 CTOR 这样的模式<type>

c++ operator overloading how to implement the pattern like the ctor of Mat_<type> in opencv

本文关键字:CTOR gt 模式 lt type Mat 重载 运算符 OpenCV 实现 C++      更新时间:2023-10-16

在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元素而不是运算符,但这只是我个人的喜好。。。