为什么不将类型名模板参数隐式识别为类型?
Why aren't typename template parameters implicitly recognized as types?
经常在 C++ class 定义中,尤其是在库、特征 class 等中,您会看到类似于以下片段的代码:
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 模板参数自动定义类型,即允许删除两个 using 行,并将 Foo<A,B>::Bar
识别为 A
和 Foo<C,D>::Baz
作为 D
?
这甚至不应该破坏现有代码,因为在 Foo 中,标识符 Bar 和 Baz 已经被采用了。
参数名称不是正在声明的实体的一部分。对于函数和模板都是如此。以下代码只声明了两个独立的实体:
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
所有从参数名称派生附加结构的尝试都必须处理这种情况。该领域最流行的请求之一是命名函数参数;迄今为止,还没有令人满意的延期提案。
在某种程度上,所有此类提案都需要将参数名称作为声明实体的一部分。例如,对于函数,这会引发一个问题,即参数名称是否需要被破坏并暴露给链接器。
经常在 C++ class 定义中,尤其是在库、特征 class 等中,您会看到类似于以下片段的代码:
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 模板参数自动定义类型,即允许删除两个 using 行,并将 Foo<A,B>::Bar
识别为 A
和 Foo<C,D>::Baz
作为 D
?
这甚至不应该破坏现有代码,因为在 Foo 中,标识符 Bar 和 Baz 已经被采用了。
参数名称不是正在声明的实体的一部分。对于函数和模板都是如此。以下代码只声明了两个独立的实体:
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
所有从参数名称派生附加结构的尝试都必须处理这种情况。该领域最流行的请求之一是命名函数参数;迄今为止,还没有令人满意的延期提案。
在某种程度上,所有此类提案都需要将参数名称作为声明实体的一部分。例如,对于函数,这会引发一个问题,即参数名称是否需要被破坏并暴露给链接器。