`operator<<`用C ++中的逗号分隔值

时间:2013-06-12 21:15:43

标签: c++ opencv operator-overloading comma-operator

以下语法适用于OpenCV

Mat R = (Mat_<double>(4, 4) <<
        1,          0,           0, 0,
        0, cos(alpha), -sin(alpha), 0,
        0, sin(alpha),  cos(alpha), 0,
        0,          0,           0, 1);

它怎么样?什么运算符超载?这种表达的意义是什么?逗号运算符现在可以重载C++吗?

3 个答案:

答案 0 :(得分:4)

逗号运算符可以重载,但通常不建议使用(在很多情况下,重载的逗号会让人感到困惑)。

上面的表达式为4 * 4矩阵定义了16个值。如果您想知道如何做到这一点,我将展示一个更简单的例子。假设我们希望能够编写类似

的内容
MyVector<double> R = (MyVector<double>() << 1 , 2 , 3);

然后我们可以定义MyVector,以便<<,运算符向向量添加新值:

template<typename T> 
class MyVector: public std::vector<T> {
 public:
  MyVector<T>& operator << (T value) { push_back(value); return *this; }
  MyVector<T>& operator , (T value) { push_back(value); return *this; }
  ...
};

答案 1 :(得分:3)

以下是实际代码taken from here,您可以看到正在使用operator,

template<typename _Tp> template<typename T2> inline MatCommaInitializer_<_Tp>&
MatCommaInitializer_<_Tp>::operator , (T2 v)
{
     CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
     *this->it = _Tp(v); ++this->it;
    return *this;
}

它接受下一个值并简单地将其放入矩阵中,递增迭代器,然后返回对MatCommaInitializer对象的引用(这样运算符可以链接在一起)。

答案 2 :(得分:2)

以下是OpenCV的源代码。我们可以知道MatCommaInitializer_类重载了,运算符,并在全局静态字段中重载了<<运算符。

`
core.hpp
...
template<typename _Tp> class MatCommaInitializer_
{
public:
    //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
    MatCommaInitializer_(Mat_<_Tp>* _m);
    //! the operator that takes the next value and put it to the matrix
    template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
    //! another form of conversion operator
    Mat_<_Tp> operator *() const;
    operator Mat_<_Tp>() const;
protected:
    MatIterator_<_Tp> it;
};
...
`

`
mat.hpp
...
template<typename _Tp, typename T2> static inline MatCommaInitializer_<_Tp>
operator << (const Mat_<_Tp>& m, T2 val)
{
    MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
    return (commaInitializer, val);
}
...
`

所以代码的工作过程如下:

  1. Mat_(4,4)创建一个包含4个double类型的第4行列元素的实例。

  2. 然后调用<<重载运算符并返回MatCommaInitializer_实例。

  3. 然后调用,重载运算符并返回MatCommaInitializer_实例,依此类推。

  4. 最后调用构造函数Mat(const MatCommaInitializer_<_Tp>& commaInitializer)