2014-09-08 2 views
19

Следующий C++ 11 код успешно компилируется на моей GCC 4.8:C++ 11 частный конструктор по умолчанию

struct NonStack 
{ 
private: 
    NonStack() = default; 
public: 
    static NonStack* Create(){ 
    return new NonStack; 
    } 
}; 
NonStack a; 

int main() { } 

Однако следующее дает ошибку компиляции:

struct NonStack 
{ 
private: 
    NonStack(){} 
}; 

NonStack a; 

int main() { } 

Почему первый один успех? Должен ли частный дефолтный конструктор запретить создание объекта через NonStack a;?

+2

Ваш код действительно выполняет [компиляцию] (http://coliru.stacked-crooked.com/a/55199811d96f1af7) на gcc4.8, но 4.9 отклоняет его (как следует). – Praetorian

+8

Этот вопрос был бы лучше, если бы в нем возник вопрос. –

+0

Вы также можете '= удалить;' конструктор. Он должен вести себя так, как ожидалось. – glampert

ответ

17

Это ошибка gcc 54812, компилятор не учитывает спецификаторы доступа для явно заданных специальных функций-членов. Ошибка 56429, которая отмечена как дубликат предыдущей, имеет тестовый пример, который почти идентичен примеру в вопросе.

Решения должны обновиться до gcc4.9, что решает проблему. Или создайте пустое тело для конструктора, вместо того, чтобы явно дефолтировать его, как вы это делали во втором примере.

+3

Примечание: эта ошибка связана с [проблема с базовым языком 1507] (http: //www.open- std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1507). Это не было ошибкой в ​​GCC. Стандарт действительно использовал, чтобы сказать, что, поскольку конструктор был тривиальным, конструктор не был вызван, и если конструктор не вызывается, то факт, что он «частный», не является проблемой. – hvd

+0

@hvd Согласился, что частный тривиальный конструктор, недоступный, но хорошо сформированный, был дефектом в стандарте, но отчет об ошибке gcc по-прежнему указывает на ошибку, поскольку они применяют эту логику к недоступным тривиальным деструкторам. Ответ может быть сформулирован лучше, хотя, и я обнов его через некоторое время. – Praetorian

+0

Ах, я пропустил это, у стандарта есть соответствующие формулировки для этого дольше. Возможно, интересный, стандарт по-прежнему не имеет запрета на «удаление» указателя на неполный тип класса, который имел бы недоступный тривиальный деструктор, это только неопределенное поведение, если деструктор фактически нетривиален. – hvd