Наследовать от типа const, переданного как параметр шаблона
Следующий код недействителен:
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 reports
<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
Благодаря @TC мы имеем:
Согласно [temp.param]/3:
Параметр типа, идентификатор которого не следует за многоточием, определяет его идентификатор как typedef-name (если объявлено с class
или typename
)... в области описания шаблона.
Таким образом, он работает точно так же, как typedef
.
И затем [class.name]/5:
Если имя typedef, которое называет класс класса cv, используется там, где требуется имя класса, cv-квалификаторы игнорируются.
Следовательно, GCC прав, const
должен быть разделен при наследовании от T
, так как в этом месте требуется имя класса, а также при using T::T;
наследование конструкторов.