为什么不为std :: vector重载operator =()?

时间:2011-06-16 01:38:30

标签: c++ stl vector operator-overloading

我已经开始学习C ++了,所以我不知道在缺乏知识/经验的情况下,为什么对于新手来说看似简单的东西就像我将要描述的那样尚未出现在STL中。要将矢量添加到另一个矢量,您必须输入以下内容:

v1.insert(v1.end(), v2.begin(), v2.end());

我想知道在现实世界中人们是否只是重载+ =运算符以使其更加冗长,例如

的影响
template <typename T>
void operator+=(std::vector<T> &v1, const std::vector<T> &v2) {
    v1.insert(v1.end(), v2.begin(), v2.end());
}

所以你可以

v1 += v2;

我也把这个设置为push_back到“+ =”一个元素到最后。是否有某些原因这些事情不应该由熟练使用C ++的人完成或特别避免?

4 个答案:

答案 0 :(得分:20)

实际上,我希望以append()的重载形式看到此功能。 operator+=有点含糊不清,你的意思是将每个向量的元素相互添加吗?或者你的意思是追加?

但是,就像我说的那样,我会欢迎:v1.append(v2);这很简单,我不知道为什么不存在。

答案 1 :(得分:3)

我认为主要原因是+=的语义不明显。你有这里的含义,但是一个同样有效的含义,它是等大小向量的每个元素的元素加法。由于这种模糊性,我认为他们认为最好依靠用户直接致电insert

答案 2 :(得分:3)

只有在您不更改这些运算符的含义时,才应重载运算符。*

这意味着,例如,如果没有两个对象的乘积的数学定义,请不要重载这些对象的乘法运算符。如果存在数学对应关系,则运算符重载可以使类更方便使用,方程式以a * b + c的形式表示,而不是更冗长(a.multiply(b))。add(c)Where使用加法和乘法运算符,加法和乘法应该是意图。任何其他意义都可能使其他人感到困惑。其他一些可以接受重载运算符的类型(在我看来,首选)是智能指针,迭代器,复数,向量和bignums。

这源于C ++的一个设计目标,即应该可以定义与内置类型一样易于使用的类。当然,您可以在类上定义运算符,这些运算符也不是数学概念。您可能希望重载==和!=运算符而不是编写isEqual方法,并且可能希望重载=因为编译器的默认赋值运算符不是您想要的。

另一方面,重载操作符以执行意外操作,例如定义^将字符串转换为日语,这是模糊和危险的。你的同事们不会很高兴发现看起来像独家或比较的东西实际上是非常不同的东西。然后,解决方案是编写类,以便轻松编写清除可维护代码,无论这是否意味着使用运算符重载或避免使用它。

添加两个向量对于定义运算符而言太过模糊。正如其他人所表明的那样,许多人对这意味着什么有不同的想法,而对于字符串,人们普遍认为将两个字符串加在一起就意味着连接。在您的示例中,您是否想要对所有元素进行组件明智添加,向末尾添加元素或将两个向量连接在一起并不完全清楚。虽然这样做可能更简洁,但使用运算符重载来创建自己的编程语言并不是最好的方法。

*是的,我知道Stroustrup重载了&lt;&lt;和&gt;&gt;做流操作而不是位移。但是,与算术和指针运算符相比,这些并不经常被使用,并且可以认为现在每个人都知道如何使用cout,通常理解为&lt;&lt;和&gt;&gt;是插入器和提取器操作器。 (他最初只是尝试使用&lt;和&gt;进行输入和输出,但是这些运算符的含义在每个人的脑海中根深蒂固,代码是不可读的。)

答案 3 :(得分:2)

除了其他人提到的关于这种语法不直观且因此容易出错的内容之外,它还违背了一个好的设计规则,使得通用算法应用于各种容器自由函数和容器特定算法 - 成员函数。除了std::string之外,大多数容器都遵循这个规则,Herb Sutter因其整体设计而受到很多抨击。