【问题标题】:Fallback to copy constructor not working?回退到复制构造函数不起作用?
【发布时间】:2015-07-04 23:12:41
【问题描述】:

我认为当我删除 B 中的移动构造函数时,以下代码仍然可以正常编译,因为它仍然应该使用复制构造函数来构造 B 对象。为什么编译器现在抱怨。如果没有=delete,它不会调用复制构造函数,因为它不允许提供默认的移动构造函数!)

class B{
    public:
    B(){}
    ~B(){}
    B & operator=(const B & b){
        std::cout << " cannot move -> copy " << std::endl; 
        return *this;
    }
    B(const B & v){
        std::cout << " cannot move -> copy " << std::endl;        
    }

    // B(B && b) = delete; // uncomment this!
};


int main()
{
    B b( B{} ); 
}

使用 clang 3.6 (Live code) 的编译器输出

main.cpp:27:7: error: call to deleted constructor of 'B'

    B b( B{} );

      ^  ~~~

main.cpp:21:5: note: 'B' has been explicitly marked deleted here

    B(B && b) = delete;

    ^

1 error generated.

【问题讨论】:

  • “函数未定义”和“函数定义为已删除”不是一回事。后者表示该函数正常参与重载决议,如果实际选择则产生错误。

标签: c++ c++11 copy-constructor c++14 move-semantics


【解决方案1】:

定义已删除的函数仍被声明。除其他外,它正常参与重载决议 - 但如果重载决议实际选择了它,则程序格式错误([dcl.fct.def.delete]/2):

隐式或显式引用已删除函数的程序,而不是声明它,是格式错误的。 [注:这包括隐式或显式调用函数并形成指针或指向成员的指针 到功能。它甚至适用于未潜在评估的表达式中的引用。如果一个函数 被重载,只有当函数被重载决议选择时才会被引用。 ——尾注]

这与根本没有声明的函数不同。不存在的声明当然不会参与重载决议。

【讨论】:

  • 有一个例外:定义为已删除的 defaulted 移动构造函数或移动赋值运算符被重载决议忽略。
猜你喜欢
  • 2018-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 2015-11-02
  • 2011-07-17
  • 2013-08-24
相关资源
最近更新 更多