为什么 typename 模板参数不被隐式识别为类型?

Why aren't typename template parameters implicitly recognized as types?

提问人:einpoklum 提问时间:5/26/2016 最后编辑:einpoklum 更新时间:5/26/2016 访问量:190

问:

在 C++ 类定义中,尤其是在库、trait 类等中,您经常会看到类似于以下代码片段的代码:

template <typename Bar, typename Baz>
class Foo {
    using bar_type = Bar;
    using baz_type = Baz;
    // ... etc.
}

只有使用这些行,您以后才能引用 或 .我想知道:为什么语言标准不要求编译器使用 typename 模板参数自动定义类型,即允许删除两个 using 行,并识别为 和 as ?Foo<A,B>::bar_typeFoo<C,D>:baz_typeFoo<A,B>::BarAFoo<C,D>::BazD

这甚至不应该破坏现有的代码,因为在 Foo 中,标识符 Bar 和 Baz 无论如何都已经被占用了。

C++ 模板 语言律师 C++17 使用指令

评论

0赞 davidbak 5/26/2016
因为它们可能不是类型。例如,它们可能是一个值,例如,Ntemplate<class T, std::size_t N> struct array
5赞 juanchopanza 5/26/2016
它们并不总是需要的,公开它们意味着客户端代码可能会与它们耦合(假设你的意思是这些别名是公开的)。
1赞 davidbak 5/26/2016
另一个答案:因为自己做是微不足道的。当有人问为什么 C++ 中没有关键字时,这是给出的答案(但我手头没有参考)。super
7赞 Kerrek SB 5/26/2016
这些名称不是模板的一部分。 声明同一模板三次。就像函数参数一样。template <typename> struct X; template <typename A> struct X; template <typename Q> struct X;
1赞 davidbak 5/26/2016
@NicolBolas - 我实际上在 SO 上找到了一个参考。

答:

7赞 Kerrek SB 5/26/2016 #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

所有从参数名称派生其他结构的尝试都必须处理这种情况。该领域最流行的请求之一是命名函数参数;迄今为止,还没有关于这种延期的令人满意的提议。

在某种程度上,所有这些提案都要求将参数名称作为申报实体的一部分。例如,对于函数,这将引发一个问题,即是否需要修改参数名称并将其公开给链接器。

评论

0赞 uh oh somebody needs a pupper 5/26/2016
谁知道呢。参数名称成为函数签名的一部分的一个隐藏含义可能是,它使你面临像 Oracle 这样的公司起诉你的屁股。
0赞 einpoklum 5/26/2016
我一再被那些不知何故对为什么现状是这样的问题感到恼火的人(显然不是你)感到沮丧,并在没有评论的情况下投反对票或投票关闭 - 当有一个完全合理的答案时(这验证了问题的理由)。
0赞 Chris Beck 5/26/2016
@einpoklum:我认为这是一个很好的问题,我很高兴阅读了问题和答案。然而,我不得不承认,当我第一次读到它时,我很想投票关闭,因为与堆叠溢出无关。我猜的原因是这句话“这曾经被建议过吗?讨论?被拒绝了吗?我不认为对C++的任意历史调查可以提出很好的SO问题 - 这些问题应该是关于编程的,理想情况下,对工作的程序员而不是学者或历史学家感兴趣,IMO。如果没有那句话,我可能会投赞成票。我只是一个样本点,YMMV。
0赞 einpoklum 5/26/2016
@ChrisBeck: 1.这不一定是历史调查,因为在某些情况下,人们会说“哦,是的,这是标准委员会的常设提案”,然后你可以去阅读它,并意识到它甚至可能进入下一个标准。2. 一些程序员在编程语言的理论/学术讨论中受到启发编写代码。因此,这些问题与他们有关。不同的人有不同的笔触等。