Я пытаюсь использовать комбинацию инициализации элемента прямых данных С++ 11 и синтаксиса "using" для наследования конструкторов базового класса. Теперь с gcc 5.4.0 (на Ubuntu 16.04) я наблюдаю странную ошибку, если тип элемента данных не имеет конструктора по умолчанию. Это, вероятно, проще всего понять, если посмотреть на следующий минимальный пример:
#include <iostream>
struct Foo {
Foo(int arg) { std::cout << "Foo::Foo(" << arg << ")" << std::endl; }
};
struct Base {
Base(int arg) { std::cout << "Base::Base(" << arg << ")" << std::endl; }
};
struct Derived : public Base {
using Base::Base;
Foo foo{42};
};
int main() {
Derived derived{120};
}
Этот код компилируется и выполняется с ожидаемым поведением с clang. С gcc он не компилируется, потому что компилятор удаляет конструктор Derived::Derived(int)
:
ttt.cpp: In function ‘int main()’:
ttt.cpp:17:22: error: use of deleted function ‘Derived::Derived(int)’
Derived derived{120};
^
ttt.cpp:12:15: note: ‘Derived::Derived(int)’ is implicitly deleted because the default definition would be ill-formed:
using Base::Base;
^
ttt.cpp:12:15: error: no matching function for call to ‘Foo::Foo()’
ttt.cpp:4:3: note: candidate: Foo::Foo(int)
Foo(int arg) { std::cout << "Foo::Foo(" << arg << ")" << std::endl; }
^
ttt.cpp:4:3: note: candidate expects 1 argument, 0 provided
ttt.cpp:3:8: note: candidate: constexpr Foo::Foo(const Foo&)
struct Foo {
^
ttt.cpp:3:8: note: candidate expects 1 argument, 0 provided
ttt.cpp:3:8: note: candidate: constexpr Foo::Foo(Foo&&)
ttt.cpp:3:8: note: candidate expects 1 argument, 0 provided
Если я добавлю конструктор по умолчанию в Foo следующим образом:
Foo() { std::cout << "Foo::Foo()" << std::endl; };
также gcc может скомпилировать его. Код ведет себя точно так же, в частности, добавленный конструктор по умолчанию Foo никогда не будет выполнен.
Итак, теперь мой вопрос: действительно ли это С++ 11? Если да, я, вероятно, нашел ошибку в gcc. В противном случае, не должны ли gcc и clang выдавать сообщение об ошибке, что это недопустимо С++ 11?
Редактировать после того, как на вопрос был приятно ответил @vlad-from-moscow: эта ошибка, похоже, присутствует и в gcc 6.2, поэтому я напишу отчет об ошибке.
2nd edit: Там уже есть ошибка, которую я не нашел в первом поиске: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67054