简体   繁体   中英

c++ operator overloading how to implement the pattern like the ctor of Mat_<type> in opencv

In opencv, I can construct an object of Mat like this:

Mat mat = (Mat_<int>(2, 3) << 1, 2, 3, 4, 5, 6);

So it's convenient to initialize an instance of Mat_<type> ,and if I have a custom simplified matrix class Mat2D ,in which i will use this pattern, but how to do?
Update: I tried to use variable length parameter list, but error C2829: 'operator <<' cannot have a variable parameter list .

WARNING: DO NOT DO THIS. YOU HAVE BEEN WARNED.

You can achieve this using operator overloading, but it is a very bad idea, as I'll explain later.

I'll assume class Mat has a constructor that takes a Mat_<int> .

I'll assume class template Mat_<T> has a method, Insert() , that knows how to insert a single element into a matrix. I'll let you work this out, but it'll need a way to know where to insert it.

Using this method it is easy to overload operator<< :

template<typename T>
Mat_<T>& operator<<(Mat_<T>& mat, const T& el)
{
  mat.Insert(el);
  return mat;
}

And we can overload operator, to call this overloaded operator<< :

template<typename T>
Mat_<T>& operator,(Mat_<T>& mat, const T& el)
{
  return mat << el;
}

Everything works fine and you can use your syntax. Now I will explain why this is a bad idea.

Overloading operator<< this way is perfectly sensible. This is the insertion operator and our overload inserts an element into the matrix. This is what anybody would expect; so far, so good.

But overloading operator, is not. The meaning of this operator is "evaluate two expressions, then return the last one"; this is clearly not what our overloaded operator does. Unwary users will try to use operator , in the standard way (for instance, in a for loop) and will not understand why their code does not work. You should never overload an operator to do a non-standard operation unless you want to be hated by whoever uses your code; probably yourself sometime later.

In fact, while the standard allows overloading operator, , this is something you should probably never do, because it is impossible to write code that does the standard operation. You can consider this a mistake in the standard that is kept for backward compatibility.

And, in case you were considering overloading operator, to take two int and somehow bundle them together, not only the drawbacks are even more serious: it is illegal to overload an operator when all operands are built-in types.

So, in summary: you can do it, but it is a bad idea and will cause bugs in unexpected places of your code.

This is a combination of builder pattern with fluent interface using the inserter and comma operators as simple DSL. I do not see dangers of any kind (if done properly), since your DSL defines a very special context in which these operators apply. Have a look at boost::assign, if you are looking for inspiration. Anyway, I´d use verbal DSL elements instead of operators but this is just a matter of my personal preference...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM