When is the quot;typenamequot; keyword necessary?(什么时候是“typename需要关键字吗?)
问题描述
可能的重复:
正式来说,typename 是做什么用的?
我必须将模板放在哪里以及为什么和 typename 关键字?
考虑下面的代码:
template<class K>
class C {
    struct P {};
    vector<P> vec;
    void f();
};
template<class K> void C<K>::f() {
    typename vector<P>::iterator p = vec.begin();
}
为什么在这个例子中需要typename"关键字?还有其他必须指定typename"的情况吗?
Why is the "typename" keyword necessary in this example? Are there any other cases where "typename" must be specified?
推荐答案
简短回答:每当引用作为依赖名称的嵌套名称时,即嵌套在具有未知参数的模板实例中.
Short answer: Whenever referring to a nested name that is a dependent name, i.e. nested inside a template instance with unknown parameter.
长答案:C++ 中有三层实体:值、类型和模板.所有这些都可以有名称,仅凭名称并不能告诉您它是实体的哪一层.相反,有关名称实体性质的信息必须从上下文中推断出来.
Long answer: There are three tiers of entities in C++: values, types, and templates. All of those can have names, and the name alone doesn't tell you which tier of entity it is. Rather, the information about the nature of a name's entity must be inferred from the context.
当此推断不可能时,您必须指定它:
Whenever this inference is impossible, you have to specify it:
template <typename> struct Magic; // defined somewhere else
template <typename T> struct A
{
  static const int value = Magic<T>::gnarl; // assumed "value"
  typedef typename Magic<T>::brugh my_type; // decreed "type"
  //      ^^^^^^^^
  void foo() {
    Magic<T>::template kwpq<T>(1, 'a', .5); // decreed "template"
    //        ^^^^^^^^
  }
};
这里的名称 Magic、Magic 和 Magic必须加以解释,因为无法判断:由于 Magic 是一个模板,Magic 类型的 性质 取决于在 T 上——例如,可能存在与主模板完全不同的特化.
Here the names Magic<T>::gnarl, Magic<T>::brugh and Magic<T>::kwpq had to be expliciated, because it is impossible to tell: Since Magic is a template, the very nature of the type Magic<T> depends on T --  there may be specializations which are entirely different from the primary template, for example.
使 Magic 成为依赖名称的原因是我们位于模板定义中,其中 T 是未知的.如果我们使用 Magic,情况会有所不同,因为编译器知道(你保证!)Magic 的完整定义.
What makes Magic<T>::gnarl a dependent name is the fact that we're inside a template definition, where T is unknown. Had we used Magic<int>, this would be different, since the compiler knows (you promise!) the full definition of Magic<int>.
(如果您想自己测试,这里有一个您可以使用的 Magic 示例定义.请原谅在专业化中为简洁起见使用 constexpr;如果您有一个旧的编译器,可以随意将静态成员常量声明更改为旧式 pre-C++11 形式.)
(If you want to test this yourself, here's a sample definition of Magic that you can use. Pardon the use of constexpr in the specializaation for brevity; if you have an old compiler, feel free to change the static member constant declaration to the old-style pre-C++11 form.)
template <typename T> struct Magic
{
  static const T                    gnarl;
  typedef T &                       brugh;
  template <typename S> static void kwpq(int, char, double) { T x; }
};
template <> struct Magic<signed char>
{
  // note that `gnarl` is absent
  static constexpr long double brugh = 0.25;  // `brugh` is now a value
  template <typename S> static int kwpq(int a, int b) { return a + b; }
};
用法:
int main()
{
  A<int> a;
  a.foo();
  return Magic<signed char>::kwpq<float>(2, 3);  // no disambiguation here!
}
                        这篇关于什么时候是“typename"需要关键字吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:什么时候是“typename"需要关键字吗?
				
        
 
            
        基础教程推荐
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
 - 如何检查GTK+3.0中的小部件类型? 2022-11-30
 - 这个宏可以转换成函数吗? 2022-01-01
 - 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
 - 我有静态或动态 boost 库吗? 2021-01-01
 - 如何在 C++ 中初始化静态常量成员? 2022-01-01
 - 如何通过C程序打开命令提示符Cmd 2022-12-09
 - 常量变量在标题中不起作用 2021-01-01
 - 在 C++ 中计算滚动/移动平均值 2021-01-01
 - C++结构和函数声明。为什么它不能编译? 2022-11-07
 
    	
    	
    	
    	
    	
    	
    	
    	
						
						
						
						
						
				
				
				
				