我在VS2019中具有以下代码(尚未与其他编译器进行测试。
class A
{
// A should be a pure virtual class
};
class B
{
const A* member;
public:
B(const A& arg) : member{ &arg } {}
// Solves the problem
// B(const A&& arg) = delete;
void setA(const A& arg) { member = &arg; }
// Solves the problem
// setA(const A&& arg) = delete;
void setA(const A& arg) { member = &arg; }
};
int main()
{
B b(A{});
b.setA( A{} );
return 0;
}
现在,在set函数中的行为是预期的-它不接受右值。另一方面,构造函数愉快地接受一个rvalue而不发出警告或编译器错误。如我所见,在构造函数的情况下,编译器采用了复制语义,但在第二种情况下,则可以正确地解决它。如果我通过A&而不是const A&
,则不会发生此行为是否有一种方法可以强制编译器在构造函数中不接受右值?解决该问题的一种方法是删除B(const A &&)构造函数。有没有更优雅的方法/统一的方法呢?使构造函数显式仍然不能解决问题。
对于构造函数,删除不仅是最优雅的方法,而且是推荐的方法(5的规则-0的规则)。
[b.setA( A{} );
将同时接受右值引用和常规引用。
B b(A{});
A a;
b.setA( a );
为避免这种情况,您必须使用删除重载版本:
void setA(const A&& arg) = delete;