使用typename关键字与模板函数参数 [英] Use of typename keyword with template function parameters
问题描述
在C ++中,需要使用 typename
关键字,因此编译器可以在模板中消除嵌套类型和嵌套值之间的歧义。但是,在某些情况下,不可能存在歧义,例如当派生类从嵌套类类型继承时。
In C++, the typename
keyword is needed so the compiler can disambiguate between nested types and nested values in templates. However, there are certain situations where no ambiguity is possible, such as when a derived class inherits from a nested class type.
template <class T>
class Derived : public T::type
{ };
这里不需要 typename
关键字,事实上甚至不允许。这是有道理的,因为上下文消除了歧义。这里, T :: type
必须引用一个类型,因为你显然不能继承一个值。
Here the typename
keyword is not required, and is in fact not even allowed. This makes sense, because the context removes the ambiguity. Here, T::type
must refer to a type, since you obviously can't inherit from a value.
我认为同样的事情对于函数模板参数是成立的。
I would think the same thing would hold true for function template parameters.
template <class T>
void foo(const T::type& v)
{
}
在这种情况下,上下文清楚地表明 T :: type
必须引用一个类型,因为函数参数不能是值。然而,编译器不接受这一点。它需要 const typename T :: type&
。这似乎不一致。为什么语言允许在继承的上下文中嵌套类型的隐式假设,但在函数参数的上下文中不允许 ?在这两种情况下都没有歧义,所以为什么 typename
在一个而不是另一个?
In this case, the context makes it clear that T::type
must refer to a type, since a function parameter can't be a value. Yet, the compiler doesn't accept this. It wants const typename T::type&
. This seems inconsistent. Why does the language allow the implicit assumption of a nested type in the context of inheritance, but not in the context of function parameters? In both cases there can be no ambiguity, so why the need for typename
in one but not the other?
推荐答案
如果你稍微改变你的声明,你会得到一个完整的不同的故事
If you slightly change your declaration, you get an entire different story
template <class T>
void foo(T::type& v);
这不再是明确的。它可以声明由 AND
表达式初始化的 void
类型的变量。整个声明将被模板化。当然,这在语义上都是废话,但它在语法上是好的。
That isn't unambiguous anymore. It could declare a variable of type void
that is initialized by a bit-wise AND
expression. The entire declaration would be templated. Of course, this semantically is all nonsense, but it syntactically is alright.
一个单独的 const
的外观在语法上使它清楚,但是它的上下文依赖太多,编译器。它必须记住,它读取一个 const
或任何其他这样的事情,当它解析 T :: type
之后它需要记住把这个名字当作一个类型。它也会进一步膨胀已经复杂的标准超越信念。
The appearance of a single const
syntactically makes it unambiguous, but it's too much context dependence to make this work in a compiler. It has to remember that it read a const
or any other such thing, and when it parses the T::type
after it will need to remember to take this name as a type. It would also further bloat the already complicated Standard beyond belief.
让我们再次更改您的函数声明
Let's again change your function declaration
template <class T>
void foo(const T::type);
甚至不会出现 const
提供了无歧义的解析。它应该是一个具有未命名参数的函数声明,还是应该是一个无效的参数名称的函数声明,它错过了它的类型?参数的名称由 declarator-id
解析,它也可以是限定名。这里, const
将属于类型说明符,而 T :: type
将由编译器解析作为参数的名称,缺少 typename
。这完全是胡说八道,但在语法上有效。
Not even the appearance of const
in there provides for a unambiguous parse. Should it be a function declaration with an unnamed parameter, or should it be a function declaration with an invalid parameter name that misses its type? A parameter's name is parsed by a declarator-id
, which can also be a qualified name. So here, the const
will belong to the type specifiers, while the T::type
will be parsed by the compiler as the name of the parameter, in absence of a typename
. That is totally nonsense too, but is syntactically valid.
在基类名称的情况下,名称查找本身表示忽略非类型名称。因此,您可以免费省略 typename
:名称查找会导致更高级别的编译器模块引用一个类型,或名称查找将给出错误。
In the case of base-class names name lookup itself states that non-type names are ignored. So you get omission of typename
for free: The name that name lookup yields to more higher level modules of the compiler either refers to a type, or name lookup will have given an error.
我写了一个关于在依赖名称上放置模板和typename的位置。
这篇关于使用typename关键字与模板函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!