我不记得是哪一次谈话,但最近我看了一些来自CppCon 2017的演讲,并且有人提到了某种旁注,唯一真正的重载方式是以operator=下列方式:
class test {
public:
test& operator=(const test&) &;
};
Run Code Online (Sandbox Code Playgroud)
他明确强调了尾随&但没有说明它做了什么.
那它是做什么的?
dfr*_*fri 10
Ref-qualifiers不是C++ 17的特性(查看问题的标签),但是是C++ 11中引入的一个特性.
struct Foo
{
void bar() const & { std::cout << "const lvalue Foo\n"; }
void bar() & { std::cout << "lvalue Foo\n"; }
void bar() const && { std::cout << "const rvalue Foo\n"; }
void bar() && { std::cout << "rvalue Foo\n"; }
};
const Foo&& getFoo() { return std::move(Foo()); }
int main()
{
const Foo c_foo;
Foo foo;
c_foo.bar(); // const lvalue Foo
foo.bar(); // lvalue Foo
getFoo().bar(); // const rvalue Foo
Foo().bar(); // rvalue Foo
}
Run Code Online (Sandbox Code Playgroud)
有关简要介绍,请参阅以下博客文章:
为了解释你从CppCon谈话中重新引用的引用的意图,
"......唯一真正的超载方式
operator=......"
我们访问[over.match.funcs]/1,/ 4&/ 5 [强调我的]:
/ 1 [over.match.funcs]的子条款描述了在使用重载决策的每个上下文中提交给重载决策的候选函数集和参数列表....
/ 4对于非静态成员函数,隐式对象参数的类型是
(4.1) - "左值参考CV
X"为声明的函数不具有REF-限定符或与所述&REF-限定符(4.2) -
X使用&&ref-qualifier 声明的函数的"rvalue reference to cv "where
X是函数所属的类,cv是成员函数声明的cv-qualification..../ 5 ...对于在没有ref-qualifier的情况下声明的非静态成员函数,还应用一个附加规则:
- (5.1) - 即使隐式对象参数不是const限定的,只要在所有其他方面可以将参数转换为隐式对象参数的类型,就可以将rvalue绑定到参数.[注意:这样的参数是rvalue的事实不会影响隐式转换序列的排名. - 结束说明]
从上面的/ 5开始,出现以下重载(&省略了显式引用限定符)
struct test
{
test& operator=(const test&) { return *this }
}
Run Code Online (Sandbox Code Playgroud)
允许将值分配给r值,例如
int main()
{
test t1;
t1 = test(); // assign to l-value
test() = t1; // assign to r-value
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我们使用&ref-qualifier 显式声明重载,[over.match.funcs] /5.1不适用,并且只要我们不提供使用&&ref-qualifier 声明的重载,r值赋值将不会允许.
struct test
{
test& operator=(const test&) & { return *this; }
};
int main()
{
test t1;
t1 = test(); // assign to l-value
test() = t1; // error: passing 'test' as 'this' argument discards qualifiers
}
Run Code Online (Sandbox Code Playgroud)
&在声明自定义赋值运算符重载是"唯一真正的重载方式operator="时,我不会对是否明确包含ref-qualifier提出任何意见,但是我敢于推测,那么我会猜测这样一个语句背后的意图如上所述,是对 -r-value赋值的排除.
根据http://en.cppreference.com/w/cpp/language/member_functions&,您的成员函数声明
如下lvalue ref-qualifier。
换句话说,它需要this是左值(隐式对象参数具有对 cv 限定的 X 的左值引用类型)。还有&&,它需要this是 r 值。
从文档复制( const、易失性和引用限定成员函数):
#include <iostream>
struct S {
void f() & { std::cout << "lvalue\n"; }
void f() &&{ std::cout << "rvalue\n"; }
};
int main(){
S s;
s.f(); // prints "lvalue"
std::move(s).f(); // prints "rvalue"
S().f(); // prints "rvalue"
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
742 次 |
| 最近记录: |