Rim*_*imo 18 c++ language-design operator-overloading rvalue temporary-objects
我相信表达式T()创建了一个rvalue(由标准).但是,以下代码编译(至少在gcc4.0上):
class T {};
int main()
{
T() = T();
}
Run Code Online (Sandbox Code Playgroud)
我在技术上知道这是可能的,因为成员函数可以在temporaries上调用,而上面只是调用operator =在从第一个创建的rvalue临时T().
但从概念上讲,这就像为rvalue分配一个新值.是否允许这样做有充分的理由吗?
编辑:我发现这个奇怪的原因是它在内置类型上被严格禁止,但允许在用户定义的类型上使用.例如,int(2) = int(3)不会编译,因为这是"赋值中的无效左值".
所以我想真正的问题是,这种有点不一致的行为是否构成了语言的原因?还是出于某种历史原因?(例如,在rvalue表达式上只允许调用const成员函数在概念上会更健全,但是这可能无法完成,因为这可能会破坏一些现有代码.)
Inv*_*rse 13
这纯粹是因为操作符超载,以及你可能会超载operator =以执行更奇特的操作,例如打印到控制台,或锁定互斥锁,或任何其他东西.
是的,您要为右值分配新值.更确切地说,您operator =在rvalue上调用成员函数.由于您没有使用内置赋值运算符,为什么您认为这应该是一个问题?operator =是类的成员函数,在大多数方面类似于类的任何其他成员函数,包括它可以在rvalues上调用的事实.
您还应该考虑这样一个事实,即"作为右值"是表达式的属性,而不是对象的属性.这是事实,T()表达式计算结果为右值.然而,T()表达式产生的临时对象仍然是一个对象,也可以作为左值进行访问.例如,可以在赋值结果上调用其他一些成员函数,它将通过*this左值看到临时对象的"新"(新分配)值
(T() = T()).some_member_function();
Run Code Online (Sandbox Code Playgroud)
您还可以通过将const引用附加到它来延长临时的生命周期,并且通过 正如约翰内斯在评论中正确指出的那样,这不会将其附加到临时性的.const T& r = T() = T();的值r将是对象的"新"值.
您可以限制operator =仅适用于C++ 0x中的左值:
class T
{
public:
T& operator=(const T&) & = default;
};
Run Code Online (Sandbox Code Playgroud)
这就是为什么可以实现标准库中的几个类。例如考虑std::bitset<>::operator[]
// bit reference:\nclass reference {\n friend class bitset;\n reference();\npublic:\n \xcb\x9creference();\n reference& operator=(bool x); // for b[i] = x;\n reference& operator=(const reference&); // for b[i] = b[j];\n bool operator\xcb\x9c() const; // flips the bit\n operator bool() const; // for x = b[i];\n reference& flip(); // for b[i].flip();\n};\n\nreference operator[](size_t pos); // for b[i];\nRun Code Online (Sandbox Code Playgroud)\n\n如果这样做, bits[i] = true您就可以将某个值准确地分配给类类型的右值。返回的代理operator[]可以访问空间有效地打包成整数的位。
| 归档时间: |
|
| 查看次数: |
717 次 |
| 最近记录: |