std::vector运算符==:值还是参考比较? P>所以,我试图在C++中在CooGooCo上提出一个解决方案,并提出了这个片段,只是我意识到我不知道它是如何工作的。我不知道为什么这两种情况都是正确的

std::vector运算符==:值还是参考比较? P>所以,我试图在C++中在CooGooCo上提出一个解决方案,并提出了这个片段,只是我意识到我不知道它是如何工作的。我不知道为什么这两种情况都是正确的,c++,vector,C++,Vector,有人知道标记为line:的行是真的,是因为x==&x还是因为x+2在===的左侧之前计算 #include <iostream> #include <vector> std::vector<int>& operator+ ( std::vector<int> &v, int val ) { v.push_back(val); return v; } int main() { std::vector<

有人知道标记为
line:
的行是真的,是因为x==&x还是因为x+2在===的左侧之前计算

#include <iostream>
#include <vector>

std::vector<int>& operator+ ( std::vector<int> &v, int val )
{
    v.push_back(val);
    return v;
}

int main()
{
    std::vector<int> x;
    std::vector<int> y = x + 2; // y is a copy of x, and x is [2]

    // how are both of these are true?
    std::cout << (x==y) << "\n";    // value comparison [2]==[2]
line:
    std::cout << (x==x+2) << "\n";  // reference comparison? &x == &(x+2)

    // not sure if this is relevant
    std::cout << (x+2==x) << "\n";  // also true

    return 0;
}
#包括
#包括
标准::向量和运算符+(标准::向量和v,int-val)
{
v、 推回(val);
返回v;
}
int main()
{
std::向量x;
std::vector y=x+2;//y是x的副本,x是[2]
//这两个是怎么回事?
std::cout执行词典比较,检查
lhs
rhs
的大小是否相同,然后逐个元素进行比较

代码的问题在于,您正在将
x+2
赋值给
y
,而加法运算符正在修改
lhs
,就像
+=
运算符一样

在这里:


std::vector::operator==()
是(通常是?)一个函数,这是C++03中的一个序列点,这意味着在调用它之前需要完全评估它的所有参数

这两个参数解析为同一个参考(向量x),因此它的计算结果自然为true

这是因为操作符+从不创建新对象,它只是修改一个对象

事实上,它相当于此代码:

std::vector<int> x;
x.push_back(2);
std::cout << (x==x) << "\n"; // this is no surprise
std::向量x;
x、 推回(2);

std::cout对于标准容器,
操作符==
被重载为。这反过来在iter上起作用,并通过解除锁定应用比较,如
*it1==*it2
中所示。因此,不需要副本

表达式
x==x+2
operator==(x,x+2)
相同。两个操作数都是在函数调用之前求值的,因为
x+2
修改
x
,所以两个操作数都是相同的。因此等式成立

令人惊讶的是,您在重载
+
-运算符方面的非传统设计选择。这是一种非常糟糕的做法,也是任何合作项目中的禁忌。如果您绝对必须重载运算符,那么只有当它们按照预期的行为时,才遵循既定的语义,并且并不令人惊讶
+
-运算符将按值返回一个新对象,并使操作数不受影响。如下所示:

std::vector<int> operator+(std::vector<int> v, int n)
{
    v.push_back(n);
    return v;
}
std::vector操作符+(std::vector v,int n)
{
v、 推回(n);
返回v;
}

这种混淆源于
+
的非常规定义。通常,它会返回其参数的修改副本,而参数本身保持不变。由于运算符的行为更像
+=
,修改其参数并返回对其的引用,这大致相当于:

x.push_back(2), x == x
将修改后的向量与自身进行比较


C++总是比较值,从不引用;如果您想要引用比较,那么您必须显式地比较地址,
&x==&y

完全这样做。gcc 4.5.3.Operator
+
应该按值返回,并且不更改输入参数,如以下所示:
std::vector Operator+(const::vector&v,int val);
我想知道标准是否允许在这里返回'false'。@KennyTM:不,修改向量的函数调用是在进行比较的函数调用之前排序的。@KennyTM:是的。对于库定义的类型和内置类型,不允许重载
运算符+
,所以它是UB。你确定吗?据我所知,我是它是在一个向量上附加一个int,然后返回对同一个向量的引用。不是这样吗?@NathanAndrewMullenax是的,完全肯定。你在操作符中修改
x
。@NathanAndrewMullenax:这就像说(如果
a
b
int
s)
b=(a+=2)
a
b
最终都会得到相同的结果。对,我认为我们在这一点上是一致的。因此代码注释。我的意思是,“你确定吗?”意思是“你确定我不明白重载运算符在做什么吗?”@juanchopanza我认为itjax是说x和x+2(而不是x和y)这两个都是作为对==操作符的const引用之前被评估的,这是真的,因为==C++中的一个序列点。对我来说是有意义的。也就是说,x+1==x + 4,因为所有的副作用在被=之前被调用。RE:不好的练习。当然,整个问题是为了使一个愚蠢的编码难题产生<代码> x+ 2==x/代码>。Re:Std::平等。我对C++的了解越多,我就越觉得我的写作中有一个<代码> <代码>。)伟大的信息。谢谢。“我知道……这无疑是一个很好的解决方案。我可能已经去了一个实现模块化算术的类:
std::vector<int> operator+(std::vector<int> v, int n)
{
    v.push_back(n);
    return v;
}
x.push_back(2), x == x