我最近一直在研究 C++ 的复杂性,有一个特定的行为让我感到困惑:临时对象的规则和行为,特别是关于获取它们的地址并分配给它们。
分配给临时人员: 此外,我发现我可以分配给 UDT 的非常量临时值:
Rational a(1, 2), b(3, 4), c(5, 6);
(a * b) = c; // This line compiles
但是,尝试分配给具有内置类型的按值(即右值)返回的函数的结果会导致编译错误:
int f(int x, int y) {
return x;
}
int main() {
f(10, 5) = 12; // This line won’t compile
}
我的问题: 分配给临时人员: 如何分配给 UDT 的非常量临时变量? 这种行为是否一致,在实践中应该使用还是避免? 我搜索了各种资源,但没有找到对这些行为的令人满意的解释。有人可以解释一下这些问题吗?
提前谢谢您!
唯一的原因是内置运算符对于操作数的值类别有一定的要求。
赋值运算符 (
) 和复合赋值运算符都是从右到左分组的。 所有这些都需要一个可修改的左值作为其左操作数; [...]=
一元
运算符的操作数应为某种类型&
T
的lvalue。
Fr 例如,
&4
无效,因为 4
是纯右值。
运算符重载可以绕过这些规则,因为
&some_rational
只是转换为函数调用。如果 Rational
有一个重载的 &
运算符,您可以执行 &Rational{}
,它将获取纯右值的地址。如果 Rational
有一个重载的 =
运算符(实际上所有类类型都有),您可以执行 Rational{} = ...
来分配纯右值。这些表达式对于内置 &
和 =
运算符来说是不可能的。
请注意,您可以使用引用限定符禁用此行为:
struct Rational {
/* ... */
// the & ref-qualifier means that the = operator only works with lvalues
Rational& operator=(const Rational& other) &;
/* something */ operator&() const &;
};