使用带有模板函数参数的 typename 关键字

时间:2023-03-09
本文介绍了使用带有模板函数参数的 typename 关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

在 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);

这不再是明确的了.它可以声明一个 void 类型的变量,该变量由按位 AND 表达式初始化.整个声明将被模板化.当然,这在语义上都是无稽之谈,但从句法上来说是没问题的.

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 将被编译器解析为参数的名称,在没有 <代码>类型名称.这也完全是无稽之谈,但在语法上是有效的.

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 关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:编译时常量 id 下一篇:在 C++0x 中专门针对 lambda 的模板

相关文章