以下语法在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++
中是否可以重载逗号操作符?逗号操作符可以重载,但通常不建议这样做(在许多情况下,重载的逗号会引起混淆)。
上面的表达式为4*4矩阵定义了16个值。如果您想知道这是如何实现的,我将展示一个更简单的示例。假设我们希望能够写像
这样的东西MyVector<double> R = (MyVector<double>() << 1 , 2 , 3);
则可以定义MyVector,使<<
和,
操作符向vector添加新值:
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; }
...
};
下面是这里的实际代码,您可以看到正在使用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;
}
它取下一个值并简单地将其放入矩阵中,对迭代器加1,然后返回对MatCommaInitializer
对象的引用(因此这些操作符可以链接在一起)。
下面是OpenCV的源代码。我们可以知道类matcomainitializer_重载了,
操作符,并重载了全局静态字段中的<<
操作符。
`
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);
}
...
`
所以你的代码的工作过程如下:
Mat_(4,4)创建一个包含4行4列双类型元素的实例
然后调用
<<
重载操作符并返回MatCommaInitializer_ instance然后调用
,
重载操作符并返回MatCommaInitializer_实例,以此类推。最后调用构造函数
Mat(const MatCommaInitializer_<_Tp>& commaInitializer)