Наследовать от типа const, передаваемого в качестве параметра шаблона - PullRequest
0 голосов
/ 25 мая 2018

Следующий код недействителен:

struct base {
};

struct inherit : const base {
};

Вы не можете наследовать от типа const.

Меняется ли ситуация, когда используются шаблоны?Другими словами, действителен ли этот код:

struct base {
};

template<typename T>
struct inherit : T {
    using T::T;
};

int main() {
    inherit<base const>{};
}

gcc говорит, что все в порядке, но clang сообщает

<source>:6:2: error: 'const base' is not a direct base of 'inherit<const base>', cannot inherit constructors

        using T::T;

        ^        ~

<source>:10:2: note: in instantiation of template class 'inherit<const base>' requested here

        inherit<base const>{};

        ^

1 error generated.

Compiler returned: 1

Чтобы сделать Clang счастливым, мне нужно сделать что-то вроде этого:

template<typename T>
struct inherit : T {
    using U = std::remove_const_t<T>;
    using U::U;
};

Какая версия верна?Или ни один из них не является правильным, и мне нужно наследовать от std::remove_const_t<T>?

1 Ответ

0 голосов
/ 25 мая 2018

Благодаря @ TC имеем:

По [temp.param] / 3 :

A параметр типа , чей идентификатор не следует за многоточием, определяет идентификатор как имя_определения типа (если объявлено с помощью class или typename) ...в области объявления шаблона.

Так что он работает так же, как typedef.

А затем [class.name] / 5 :

Если typedef-name с именами cv-qualified тип класса используется там, где требуется class-name , то cv-qualifiers игнорируются.

Следовательно, GCC верен, const должен быть удален при наследовании от T, поскольку имя-класса требуется в этой точке , а также в using T::T; наследующих конструкторах декларации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...