在构造函数中传递 const 引用时如何强制编译器不接受右值

How to force the compiler not to accept rvalues when passing const reference in constructors

我在 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 函数中的行为符合预期 - 它不接受右值。另一方面,构造函数在没有警告或编译器错误的情况下愉快地接受右值。正如我所看到的,编译器在构造函数的情况下假定复制语义,但在第二种情况下正确解析它。 如果我传递 A& 而不是 const A&

,则不会发生此行为

有没有办法强制编译器不接受构造函数中的右值? 解决该问题的一种方法是删除 B(const A&&) 构造函数。有没有更优雅的方式/统一的方式来做到这一点?使构造函数显式化仍然不能解决问题。

编辑 - 建议的 link 没有回答我的问题。正如我的问题中已经提到的解决方案(即明确删除 const 右值引用)。我在问除了显式删除重载是否还有另一种方法。我也试图了解它是否是一个错误(在编译器或标准中)或者它应该是这样。

如果是构造函数,删除不仅是最优雅的,而且是推荐的方法(五法则-零法则)。

b.setA( A{} ); 将接受右值引用和一般引用。

B b(A{});
A a;
b.setA( a ); 

为避免这种情况,您必须使用删除重载版本:

void setA(const A&& arg) = delete;