【发布时间】:2019-02-27 14:50:08
【问题描述】:
在下面的代码中,我期待函数 Foo f(Foo& x) 返回一个右值,但令我惊讶的是它没有。所以我开始测试一些案例,以找出返回值的“左值”和“右值”背后的逻辑。事实证明,返回一个类类型的命名变量是一个左值。也许我错过了什么
#include <iostream>
class Foo
{
int val;
public:
Foo(int value=10)
{
val = value;
};
Foo(Foo& other)
{
std::cout << "copy ctor used" << std::endl;
val = other.val;
};
Foo(Foo&&)
{
std::cout << "move ctor used" << std::endl;
};
Foo operator=(Foo& other)
{
std::cout << "copy assign used" << std::endl;
val = other.val;
return *this;
}
Foo operator=(Foo&& a)
{
std::cout << "move assign used" << std::endl;
return *this;
}
void set(int value) { val = value; };
int get() { return val; };
};
int z = 20;;
int case1()
{
return z;
};
int case2(int x)
{
return x;
};
Foo case3(Foo x)
{
return x;
};
Foo case4(Foo& x)
{
return x;
};
Foo y;
Foo case5()
{
return y;
}
Foo& case6(Foo& x)
{
return x;
};
Foo case7()
{
Foo x;
return x;
}
int main()
{
/*case1() = 50;*/ // as expected: not OK the return value is not an lvalue
int c = 40;
/*case2(c) = 50; */ // as expected: not OK the return value is not an lvalue
Foo a;
Foo b = 30;
case3(a) = b; // OK: not at all expected the return value is an lvalue
// I don't see the difference with case 2
//copy construction of the argument and return value
//copy assigning of b
case4(a) = b; //OK: behaving exactly like case 3 except for the copy construction
// of the argument and the return value
// copy assigning taking place as expected
case5() = b; // same as case 3
case6(a) = b; //just copy assigning taking place
// the same reference to a is returned
case7() = b; // same as before
std::cin.get();
}
【问题讨论】:
-
你的结论是错误的。你假设
=只能应用于可能运算符重载的世界中的左值是错误的。 -
在函数按值返回
Foo并分配给它的情况下,您只是在调用临时对象的operator=。您可以通过提供operator=的不同引用限定符版本来进一步区分这些情况,请参阅here。 -
另一个类似主题的问题(虽然可能不是重复的)stackoverflow.com/questions/51172341/…
-
抱歉,您真的确定要以您的经验水平深入研究价值(现代 C++ 复杂得难以置信)吗?
-
@SergeyA 我们总有一天要处理这样的事情,所以越快越好:)
标签: c++