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

问题描述 投票:1回答:1

我在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 &&)构造函数。有没有更优雅的方法/统一的方法呢?使构造函数显式仍然不能解决问题。

c++11 constructor pass-by-reference
1个回答
1
投票

对于构造函数,删除不仅是最优雅的方法,而且是推荐的方法(5的规则-0的规则)。

[b.setA( A{} );将同时接受右值引用和常规引用。

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

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

void setA(const A&& arg) = delete;
© www.soinside.com 2019 - 2024. All rights reserved.