【问题标题】:Deleted copy constructor results in deleted default constructor删除的复制构造函数导致删除的默认构造函数
【发布时间】:2013-08-19 03:44:46
【问题描述】:

此代码无法使用 gcc 4.7.0 编译:

class Base
{
public:
    Base(const Base&) = delete;
}; 

class Derived : Base
{
public:
    Derived(int i) : m_i(i) {}

    int m_i;
};

错误是:

c.cpp: In constructor `Derived::Derived(int)´:
c.cpp:10:24: error: no matching function for call to `Base::Base()´
c.cpp:10:24: note: candidate is:
c.cpp:4:2: note: Base::Base(const Base&) <deleted>
c.cpp:4:2: note:   candidate expects 1 argument, 0 provided

换句话说,编译器不会为基类生成默认构造函数,而是尝试调用 deleted 复制构造函数作为唯一可用的重载。

这是正常行为吗?

【问题讨论】:

  • 是的,因为如果有任何构造函数是用户声明的,那么默认构造函数就会被抑制。
  • 为什么删除构造函数被认为是构造函数的声明?这是反直觉的。

标签: c++ c++11 deleted-functions


【解决方案1】:

C++11 §12.1/5 规定:

X默认 构造函数是类X 的构造函数,可以不带参数调用。如果 X 类没有用户声明的构造函数,则没有参数的构造函数被隐式声明为默认 (8.4)。

您的Base(const Base&amp;) = delete; 算作用户声明的构造函数,因此它会抑制隐式默认构造函数的生成。解决方法当然是声明它:

Base() = default;

【讨论】:

  • 为什么一个被删除的构造函数算作构造函数的声明?这对我来说没有意义。已删除的构造函数明确声明不允许定义此类构造函数(无论是否默认)。
  • 我发现了这个:ISO/IEC JTC1 SC22 WG21 N2346,它指出所有查找和重载解析都发生在 删除的定义被记录之前,因此这个答案是正确的。
猜你喜欢
  • 2019-05-07
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 2021-12-08
  • 2017-05-10
  • 2016-01-01
  • 1970-01-01
  • 2018-02-24
相关资源
最近更新 更多