【发布时间】:2021-09-07 13:43:05
【问题描述】:
向运算符添加 ref 限定符将消除进行右值赋值的可能性
例如,使用g++ -std=c++14 bar.cpp && ./a.out编译以下内容
#include <cstdio>
struct foo
{
void operator+=(int x) & { printf("%d\n", x+2); }
};
int main()
{
foo() += 10;
}
会给你
$ g++ -std=c++14 bar.cpp && ./a.out
bar.cpp: In function ‘int main()’:
bar.cpp:14:14: error: passing ‘foo’ as ‘this’ argument discards qualifiers [-fpermissive]
14 | foo() += 10;
| ^~
bar.cpp:6:10: note: in call to ‘void foo::operator+=(int) &’
6 | void operator+=(int x) & { printf("%d\n", x+2); }
| ^~~~~~~~
您当然可以通过添加明确的&& 来“解决”这个问题
#include <cstdio>
struct foo
{
void operator+=(int x) & { printf("%d\n", x+2); }
void operator+=(int x) && { printf("%d\n", x+3); }
};
int main()
{
foo() += 10;
}
输出
$ g++ -std=c++14 bar.cpp && ./a.out
13
但是添加const & 也会让你在结构实例上调用+=。
#include <cstdio>
struct foo
{
void operator+=(int x) & { printf("%d\n", x+2); }
void operator+=(int x) const & { printf("%d\n", x+4); }
};
int main()
{
foo() += 10;
}
输出
$ g++ -std=c++14 bar.cpp && ./a.out
14
要“修复”这个问题,必须明确删除 const &&
#include <cstdio>
struct foo
{
void operator+=(int x) & { printf("%d\n", x+2); }
void operator+=(int x) const & { printf("%d\n", x+4); }
void operator+=(int x) const && = delete;
};
int main()
{
foo() += 10;
}
输出
$ g++ -std=c++14 bar.cpp && ./a.out
bar.cpp: In function ‘int main()’:
bar.cpp:14:14: error: use of deleted function ‘void foo::operator+=(int) const &&’
14 | foo() += 10;
| ^~
bar.cpp:9:10: note: declared here
9 | void operator+=(int x) const && = delete;
| ^~~~~~~~
这是为什么?为什么添加 ref-qualifier 会隐式删除右值分配?但是添加 cv-qualifier 和 ref-qualifier 似乎隐式添加了右值赋值?
我确定我在这里遗漏了一些明显的东西。但是 Google-Wan Kenobi 似乎无法帮助我理解。
【问题讨论】:
-
看起来右值引用可转换为 const 左值引用,但不能转换为非 const 引用。甚至在显式右值引用之前也是如此:const 引用可以绑定到临时的,而非 const 的则不能。
标签: c++ constants operator-overloading c++14 ref-qualifier