为什么关键字“typename”需要合格的依赖名称,而不是合格的独立名称之前? [英] Why is the keyword "typename" needed before qualified dependent names, and not before qualified independent names?

查看:171
本文介绍了为什么关键字“typename”需要合格的依赖名称,而不是合格的独立名称之前?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class A 
{
static int iterator;
类迭代器
{
[...]
};
[...]

我(我想)了解 typename 需要这里:

 模板< class T& 
void foo(){
typename T :: iterator * iter;
[...]
}

但我不明白这里不需要 typename 的原因:

  void foo 
A :: iterator * iter;
[...]
}

>




EDIT:



编译器没有问题的原因对于后者,我发现在 A :: iterator 的情况下,在注释中回答得很好:



$ c>我不明白为什么编译器不会与 static int iterator 混淆? - xcrypt



@xcrypt,因为它知道 A :: iterator 并且可以根据使用方式选择哪一个 - Seth Carnegie






编译器需要的原因 typename 在合格的依赖名称之前,在我看来在Kerrek SB接受的答案中很好地回答。一定要阅读关于这个答案的意见,特别是这个由iammilind:



T :: A * x;,这个表达式可以为true, T :: A是一个类型,T :: A是一个值,如果A是一个类型,那么它将产生指针声明;如果A是一个值,那么它将导致乘法。

在C ++中的一个名称可能属于到三个不同层级的实体:值,类型和模板。

  struct Foo 
{
typedef int A;
static double B;
template< typename T> struct C;
};

三个名称 Foo :: A Foo :: B Foo :: C 是所有三个不同层级的示例。



在上面的例子中, Foo 是一个完整的类型,因此编译器已经知道 Foo :: A 等。但现在想象一下:

  template< typename T> struct Bar 
{
T :: A x;
};

现在我们遇到了麻烦: T :: A ?如果 T = Foo ,那么 T :: A = int ,这是一个类型,一切都很好。但是当 T = struct {char A; }; ,那么 T :: A 是一个,没有意义。

因此,编译器要求 告诉它 T :: A T :: B T :: C 都是。如果你什么也不说,它假定是一个值。如果你说 typename ,它是一个typename,如果你说模板,它是一个模板:

  template< typename T> struct Bar 
{
typename T :: A x; // ah,good,decreed typename

void foo()
{
int a = T :: B; //假设值,OK

T :: template C< int> z; // decreed template
z.gobble(a * x);
}
};

二级检查,例如 T :: B 可转换为 int ,不管 a x 和是否 C 真的具有成员函数 gobble 都被推迟,直到你真正实例化模板。但是名称是否表示值,类型或模板的规范是代码的语法正确性的基础,必须在模板定义期间提供。


class A
{
   static int iterator;
   class iterator
   {
      [...]
   };
   [...]
};

I (think I) understand the reason why typename is needed here:

template <class T>
void foo() {
   typename T::iterator* iter;
   [...]
}

but I don't understand the reason why typename is not needed here:

void foo() {
   A::iterator* iter;
   [...]
}

Can anyone explain?


EDIT:

The reason why the compiler does not have a problem with the latter, I found to be answered well in a comment:

in the case of A::iterator I don't see why the compiler wouldn't confuse it with the static int iterator ? - xcrypt

@xcrypt because it knows what both A::iterators are and can pick which one depending on how it is used – Seth Carnegie


The reason why the compiler needs typename before the qualified dependent names, is in my opinion answered very well in the accepted answer by Kerrek SB. Be sure to also read the comments on that answer, especially this one by iammilind:

"T::A * x;, this expression can be true for both cases where T::A is a type and T::A is a value. If A is a type, then it will result in pointer declaration; if A is a value, then it will result in multiplication. Thus a single template will have different meaning for 2 different types, which is not acceptable."

解决方案

A name in C++ can pertain to three different tiers of entities: Values, types, and templates.

struct Foo
{
    typedef int A;
    static double B;
    template <typename T> struct C;
};

The three names Foo::A, Foo::B and Foo::C are examples of all three different tiers.

In the above example, Foo is a complete type, and so the compiler knows already what Foo::A etc. refer to. But now imagine this:

template <typename T> struct Bar
{
    T::A x;
};

Now we are in trouble: what is T::A? if T = Foo, then T::A = int, which is a type, and all is well. But when T = struct { char A; };, then T::A is a value, which doesn't make sense.

Therefore, the compiler demands that you tell it what T::A and T::B and T::C are supposed to be. If you say nothing, it is assumed to be a value. If you say typename, it is a typename, and if you say template, it is a template:

template <typename T> struct Bar
{
    typename T::A x;    // ah, good, decreed typename

    void foo()
    {
        int a = T::B;   // assumed value, OK

        T::template C<int> z;  // decreed template
        z.gobble(a * x);
    }
};

Secondary checks such as whether T::B is convertible to int, whether a and x can be multiplied, and whether C<int> really has a member function gobble are all postponed until you actually instantiate the template. But the specification whether a name denotes a value, a type or a template is fundamental to the syntactic correctness of the code and must be provided right there during the template definition.

这篇关于为什么关键字“typename”需要合格的依赖名称,而不是合格的独立名称之前?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆