简体   繁体   English

c ++运算符重载如何实现模式,如mat_的ctor <type> 在opencv中

[英]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: 在opencv中,我可以像这样构造Mat的对象:

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? 所以初始化Mat_<type>的实例很方便,如果我有一个自定义的简化矩阵类Mat2D ,我将使用这个模式,但怎么办?
Update: I tried to use variable length parameter list, but error C2829: 'operator <<' cannot have a variable parameter list . 更新:我尝试使用变长参数列表,但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> . 我假设类Mat有一个带Mat_<int>的构造函数。

I'll assume class template Mat_<T> has a method, Insert() , that knows how to insert a single element into a matrix. 我假设类模板Mat_<T>有一个方法Insert() ,它知道如何将单个元素插入到矩阵中。 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<< : 使用这种方法很容易重载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<< : 我们可以重载operator,来调用这个重载的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. 重载operator<<这种方式是非常明智的。 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. 但是重载operator,不是。 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. 粗心的用户会尝试使用运营商,在标准方式(例如,在for循环),并会不明白为什么他们的代码不能正常工作。 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. 事实上,虽然标准允许重载operator,但这是您可能永远不会做的事情,因为编写执行标准操作的代码是不可能的。 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. 并且,如果你考虑重载operator,采用两个int并以某种方式将它们捆绑在一起,不仅缺点更严重:当所有操作数都是内置类型时,重载操作符是非法的。

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. 这是使用插入器和逗号运算符作为简单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. 我没有看到任何类型的危险(如果正确完成),因为您的DSL定义了这些运算符适用的非常特殊的上下文。 Have a look at boost::assign, if you are looking for inspiration. 如果您正在寻找灵感,请查看boost :: assign。 Anyway, I´d use verbal DSL elements instead of operators but this is just a matter of my personal preference... 无论如何,我使用口头DSL元素而不是运营商,但这仅仅是我个人的偏好......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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