以下语法适用于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++
吗?
答案 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);
}
...
`
所以代码的工作过程如下:
Mat_(4,4)创建一个包含4个double类型的第4行列元素的实例。
然后调用<<
重载运算符并返回MatCommaInitializer_实例。
然后调用,
重载运算符并返回MatCommaInitializer_实例,依此类推。
最后调用构造函数Mat(const MatCommaInitializer_<_Tp>& commaInitializer)