2013-08-16 2 views
3

Этот код не компилируется с 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 

Другими словами, компилятор не генерирует конструктор по умолчанию для базового класса и вместо этого пытается вызвать удалённый конструктор копирования как единственную доступную перегрузку.

Это нормальное поведение?

+1

Да, поскольку если какой-либо конструктор * объявлен пользователем *, конструктор по умолчанию подавляется. – Xeo

+1

Почему удаление конструктора считается объявлением конструктора? Это счетчик интуитивно понятен. – kounoupis

ответ

8

C++ 11 §12.1/5 гласит:

по умолчанию конструктор для класса X является конструктором класса X, который может быть вызван без аргумента. Если для класса X нет конструктора, объявленного пользователем, конструктор, не имеющий параметров, неявно объявляется как дефолт (8.4).

Ваш Base(const Base&) = delete; считается объявленным пользователем конструктором, поэтому он подавляет генерацию неявного конструктора по умолчанию. Обходным путем является, конечно, объявление:

Base() = default; 
+0

Почему удаленный конструктор считается объявлением конструктора? Для меня это не имеет смысла. Удаленный конструктор явно заявляет о намерении не допускать определения такого конструктора (по умолчанию или нет). – kounoupis

+1

Я нашел это: [ISO/IEC JTC1 SC22 WG21 N2346] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm#delete), в котором говорится, что весь поиск и разрешение перегрузки происходит до того, как будет отмечено удаленное определение, поэтому этот ответ правильный. – kounoupis

Смежные вопросы