Каков стандартный синтаксис соответствия для наследования конструктора шаблона?

GCC 4.8.1 принимает

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass<T>::Baseclass;
};

а MSVC - нет. С другой стороны, MSVC принимает

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass::Baseclass;
};

но GCC нет. Затем я видел в этих вопросах объявление другого типа: c++11, наследующий конструкторы шаблонов

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass::Baseclass<T>;
};

для которого MSVC предупреждает об «устаревшем стиле объявления», а GCC говорит

prog.cpp:8:24: error: ‘template<class T> class Baseclass’ used without template parameters
        using typename Baseclass::Baseclass<T>;

Я думал, что первым примером будет стандартный синтаксис соответствия. Интуитивно мне кажется, что это правильно.

Что такое синтаксис соответствия стандарту С++ 11?


person Niklas R    schedule 19.09.2014    source источник
comment
Какая версия MSVC? VS2013 не поддерживает наследование конструкторов. AFAIK, первый - правильный синтаксис. using Baseclass::BaseClass<T> должен работать в случаях, когда BaseClass сам по себе не является шаблоном класса, но имеет шаблон конструктора.   -  person Praetorian    schedule 19.09.2014
comment
@Praetorian Вот это удивительно. Но я когда-либо использовал только конструктор по умолчанию и конструктор копирования, и теперь, протестировав другой конструктор, я вижу, что вы правы. Наследуются ли конструкторы копии и конструкторы по умолчанию автоматически?   -  person Niklas R    schedule 19.09.2014
comment
Вам придется проверить стандарт, но я почти уверен, что специальные функции-члены никогда не наследуются. Они могут быть автоматически объявлены компилятором в производном классе по обычным правилам их генерации.   -  person Praetorian    schedule 19.09.2014
comment
Согласно статье Википедии, все конструкторы должны наследоваться. Так что даже что-то вроде Base::Base(int value). Редактировать: и GCC делает это: ideone.com/J0ToW2   -  person Niklas R    schedule 19.09.2014
comment
Хм? Почему есть Baseclass и BaseClass?   -  person dyp    schedule 19.09.2014
comment
Да, конечно, Base::Base(int) будет унаследован, но это не конструктор по умолчанию и не копирующий конструктор. См. [class.inhctor]/3, в котором говорится, что конструкторы по умолчанию и конструкторы копирования/перемещения исключены из набора кандидатов унаследованных конструкторов.   -  person Praetorian    schedule 19.09.2014
comment
Поскольку члены зависимых базовых классов не ищутся в независимых контекстах, я думаю, что вы должны указать аргумент шаблона для BaseClass перед ::.   -  person dyp    schedule 19.09.2014
comment
Я почти уверен, что правильным способом наследования конструкторов здесь является using Baseclass<T>::Baseclass;, а не typename, и предоставление аргумента шаблона (по крайней мере) слева от ::.   -  person dyp    schedule 19.09.2014


Ответы (1)


Ответ немного скрыт в стандарте. Объявление использования определяется как (7.3.3):

using [typename] nested-name-specifier unqualified-id;

nested-name-specifier после нескольких шагов разрешается в simple-template-id, который определяется как

template-name < [template-argument-list] >

Короче говоря, стандартный соответствующий синтаксис

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass<T>::Baseclass;
};
person user1978011    schedule 27.04.2015