C++ 中用户定义类型与内置类型的临时变量寻址和分配的差异

问题描述 投票:0回答:1

我最近一直在研究 C++ 的复杂性,有一个特定的行为让我感到困惑:临时对象的规则和行为,特别是关于获取它们的地址并分配给它们。

临时住所地址: 我注意到,当临时变量是用户定义类型(UDT)时,我可以获取它们的地址。例如:

class Rational { /*... class definition ...*/ };

int main() {
    Rational a(1, 2), b(3, 4);
    std::cout << &(a * b);  // This line compiles, and I can get the address
}

但是,如果我尝试对内置类型执行相同的操作,则会导致编译错误:

std::cout << &(2*3);  // Error

分配给临时人员: 此外,我发现我可以分配给 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 的临时地址,但不能获取内置类型的地址? 即使我可以获取它的地址,UDT 的临时值仍然是右值吗? 分配给临时人员: 如何分配给 UDT 的非常量临时变量? 这种行为是否一致,在实践中应该使用还是避免? 我搜索了各种资源,但没有找到对这些行为的令人满意的解释。有人可以解释一下这些问题吗?

提前谢谢您!

c++ assignment-operator
1个回答
0
投票

唯一的原因是内置运算符对操作数的值类别有一定的要求。例如,adress-of 运算符需要一个左值,例如

&4
无效,因为
4
是纯右值。

运算符重载可以绕过这些规则。如果

Rational
有一个重载的
&
运算符,您可以执行
&Rational{}
,它将获取纯右值的地址。如果
Rational
有一个重载的
=
运算符(实际上所有类类型都有),您可以执行
Rational{} = ...
来分配纯右值。这些表达式对于内置
&
=
运算符来说是不可能的。

请注意,您可以使用引用限定符禁用此行为:

struct Rational {
    /* ... */

    // the & ref-qualifier means that the = operator only works with lvalues
    Rational& operator=(const Rational& other) const &;

    /* something */ operator&() const &;
};
© www.soinside.com 2019 - 2024. All rights reserved.