Почему параметры шаблона typename не распознаются неявно как типы?
Очень часто в определениях классов C++, особенно в библиотеках, классах признаков и т. Д., Вы видите код, подобный следующему фрагменту:
template <typename Bar, typename Baz>
class Foo {
using bar_type = Bar;
using baz_type = Baz;
// ... etc.
}
И только с этими строками вы можете позже обратиться к Foo<A,B>::bar_type
или же Foo<C,D>:baz_type
, Мне интересно: почему языковой стандарт не требует, чтобы компилятор автоматически определял типы, используя параметры шаблона typename, то есть не разрешал удалять две строки, используя, и распознавал Foo<A,B>::Bar
как A
а также Foo<C,D>::Baz
как D
?
Это даже не должно нарушать существующий код, так как в Foo идентификаторы Bar и Baz уже заняты.
1 ответ
Имена параметров не являются частью объекта, который объявлен. Это верно как для функций, так и для шаблонов. Следующий код объявляет только два отдельных объекта:
extern void f(int, char, bool);
extern void f(int a, char b, bool c);
extern void f(int x, char b, bool z);
template <typename> struct X;
template <typename A> struct X;
template <typename T> struct X;
Обратите внимание, в частности, что следующий код прекрасно подходит:
template <typename T> struct X { void f(); }; // X<T>::f not yet defined
template <typename U> void X<U>::f() {} // now it's defined
Все попытки получить дополнительную структуру из имен параметров должны иметь дело с этой ситуацией. Один из самых популярных запросов в этой области - именованные параметры функций; до настоящего времени не было удовлетворительного предложения о таком продлении.
В некоторой степени все такие предложения потребуют сделать имена параметров частью объявленной сущности. Для функций, например, это подняло бы вопрос о том, нужно ли искажать имена параметров и выставлять их компоновщику.