Допустимо ли использовать имя класса шаблона в производном классе без аргументов шаблона? - PullRequest
4 голосов
/ 21 июня 2019

Следующий код прекрасно компилируется как с clang ++ 8.0.0 и g ++ 9.1.0 (флаги компиляции -Wall -Wextra -Werror -pedantic-errors):

template <typename>
struct Base
{
};

struct Derived : Base<int>
{
    Base base()
    {
        return Base();
    }
};

int main()
{
}

Это ошибка в этих компиляторах или особенность стандарта C ++?

Ответы [ 2 ]

9 голосов
/ 21 июня 2019

С имя введенного класса

Внутри Base<T>, Base относится (в некоторых условиях) к Base<T>.

Derived будет также использовать это имя-инъектированного класса.

8 голосов
/ 21 июня 2019

Этот код в порядке.Внутри Derived класс Base будет ссылаться на Base<int>, , потому что Derived наследуется от Base<int>.Да, это законно.

Стандарт:

14.6.1.1: Как и обычные (не шаблонные) классы, шаблоны классов имеют имя введенного класса (раздел 9).Введенное имя класса может использоваться как имя шаблона или имя типа.Когда он используется со списком аргументов шаблона, в качестве аргумента шаблона для параметра шаблона или в качестве окончательного идентификатора в подробном спецификаторе типа объявления шаблона класса друга, он ссылается на сам шаблон класса.,В противном случае оно эквивалентно имени шаблона, за которым следуют параметры шаблона шаблона класса, заключенного в <>.

Также:

3.4.3:injected-class-name класса (раздел 9) также считается членом этого класса для целей сокрытия и поиска имени.

Последнее предложение делает это.Вкратце A<B> вводит скрытый «псевдоним» A = A<B>, но только если A используется без <>.В примере он представлен в базовом классе, а производный класс наследует всех членов базового класса.

...