C ++ - matrix initialization with comma separated values

Hi, I came across this code snippet. It demonstrates how to work with the matrix structures of the dlib library.

In accordance with this, you can initialize the structure of the matrix:

M = 54.2, 7.4, 12.1, 1, 2, 3, 5.9, 0.05, 1; 

How is this possible in C ++?

Is this some kind of operator overload?

+6
source share
1 answer

Logics

This is possible by overloading operator, (operator comma) and, for example, force it to enter new floating-point values ​​in M

It should be noted that operator, must always have at least one parameter of the class type, so you have to create a class that is implicitly converted to a floating point value (for example, using the non explicit constructor with 1 argument of type double or float ).

Example

For example, we will try to do this for a wrapper type over std::vector , and we will try to make M = 1, 2, 3, 4, 5 valid expression that will result in std::vector with these elements in sequence. You will see that this is easily applicable to the matrix example below.

It should be remembered that operator= has more priority over operator, (as shown in this table of operator priority ); therefore, M = 1, 2, 3, 4, 5 will really be analyzed as: (((((M = 1), 2), 3), 4), 5) .

Given this, we start by creating our container class with operator= , which takes a single value and inserts it into the container:

 template<typename ValueType> struct container { explicit container(std::size_t n) { vec.reserve(n); } container& operator=(ValueType a) { vec.push_back(a); return (*this); } std::vector<ValueType> vec; }; 

At this point, we can define operator, as:

 template<typename ValueType> container<ValueType>& operator,(container<ValueType>& m, ValueType a) { m.vec.push_back(a); return m; } 

which just discards the new value of the element.

And now you can easily see that the following works just fine and prints 1 2 3 4 5 :

 int main() { container<int> M(5); M = 1, 2, 3, 4, 5; for (auto i : M.vec) std::cout << i << ' '; } 

Live demo

Questions

I try to avoid this technique as much as possible. This makes you have weird semantics for other operators, such as operator= , and apparently doesn't add anything to the simple use of std::initializer_list<T> .

Another example would be operator= as follows:

 container& operator=(std::initializer_list<ValueType> a) { std::copy(begin(a), end(a), back_inserter(vec)); return (*this); } 

and then just use parentheses:

 int main() { container<int> M(5); M = { 1, 2, 3, 4, 5 }; for (auto i : M.vec) std::cout << i << ' '; } 

Live demo

+12
source

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


All Articles