`operator <<` from comma separated values ​​in C ++

In opencv

The following syntax works:
 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); 

How can it be? Which operator was overloaded? What is the meaning of this expression? C++ comma operator can be overloaded at present?

+4
source share
3 answers

The comma operator can be overloaded, although it is usually not recommended (in many cases, an overloaded comma is confusing).

The above expression defines 16 values ​​for a 4 * 4 matrix. If you're curious about how this is possible, I'll show you a simpler example. Suppose we want to write something like

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

then we can define MyVector so that the << and , operators add a new value to the 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; } ... }; 
+4
source

Here is the actual code taken from here , as you can see that operator, being used:

 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; } 

It takes the next value and simply puts it in the matrix, increments the iterator and then returns a reference to the MatCommaInitializer object (so that these statements can be connected together).

+3
source

Below is the source code of OpenCV. We can know that the MatCommaInitializer_ class overloaded the operator , and overloaded the << operator in the global static field.

 ` 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); } ... ` 

So, the workflow of your code is as follows:

  • Mat_ (4, 4) creates an instance containing 4 column elements 4 rows of double type.

  • Then it calls the overloaded operator << and returns an instance of MatCommaInitializer_.

  • Then it calls the overloaded operator , and returns an instance of MatCommaInitializer_, etc.

  • Finally, it calls the Mat(const MatCommaInitializer_<_Tp>& commaInitializer) constructor Mat(const MatCommaInitializer_<_Tp>& commaInitializer)

+2
source

Source: https://habr.com/ru/post/1485886/


All Articles