提问人:einpoklum 提问时间:5/26/2016 最后编辑:einpoklum 更新时间:5/26/2016 访问量:190
为什么 typename 模板参数不被隐式识别为类型?
Why aren't typename template parameters implicitly recognized as types?
问:
在 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_type
Foo<C,D>:baz_type
Foo<A,B>::Bar
A
Foo<C,D>::Baz
D
这甚至不应该破坏现有的代码,因为在 Foo 中,标识符 Bar 和 Baz 无论如何都已经被占用了。
答:
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. 一些程序员在编程语言的理论/学术讨论中受到启发编写代码。因此,这些问题与他们有关。不同的人有不同的笔触等。
评论
template<class T, std::size_t N> struct array
super
template <typename> struct X; template <typename A> struct X; template <typename Q> struct X;