关于模板:C ++中的’typename’一词

The 'typename' word in C++

本问题已经有最佳答案,请猛点这里访问。

我正在阅读一个C++代码,我在课堂中遇到了使用EDOCX1 0的关键字定义。

这里是类定义,关键字用于受保护的部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
class CBoundary
{
    typedef CLoop<CVertex,CEdge, CFace, CHalfEdge> TLoop;

public:

    CBoundary( CBaseMesh<CVertex,CEdge,CFace,CHalfEdge> * pMesh );

    ~CBoundary();

    std::vector<TLoop*> & loops()
    {
        return m_loops;
    }

protected:

    CBaseMesh<CVertex,CEdge,CFace,CHalfEdge> * m_pMesh;

     typename std::vector<TLoop*> m_loops;

    void _bubble_sort( std::vector<CLoop<CVertex, CEdge, CFace, CHalfEdge>*> & loops);
};

这是否与typedef关键字相同?似乎有几个相关的问题但我不太明白其中的解释。

实际上,由于typename是其中一个so标签,我将列出我不理解的解释。

typename is a keyword in the C++ programming language with two
meanings. First, it can be used to declare type arguments inside a
template declaration, and is synonymous with"class." Second, it can
be used to indicate that a dependent name refers to a type. A common
cause of errors in C++ code is the omission of an essential typename.

看起来我在处理第二个用途。但我不明白什么是"从属名称"这里指的是。

我只是一个初学者用C++编写模板元编程,所以简单解释一下使用在上面的课上会很有帮助。


1
2
3
4
5
6
7
8
9
10
11
12
template <typename T>
struct A
{
    typedef T type;
    static T static_var;
};

template <typename T>
struct B
{
    typename T::type var;
};

假设我实例化了B>。不管我在第二个定义中写了T,编译器都会有效地尝试替换A。问题是,当它到达T::type时,它不知道我指的是嵌套类型还是静态变量——这两个声明看起来是相同的。

有时,它可以根据使用它的上下文来消除歧义,但通常不能。如果不能消除歧义,则必须使用typename关键字告诉它T::thing是类型的名称。


简单来说,模板代码中的"依赖名称"是在模板定义中构造的某种类型。

在您的示例中,类型cvertex、cedge、cface、chalfedge是模板参数。使用参数声明的所有其他名称都是依赖的。

它们可以是类型名,但也可以是其他类型,例如函数或变量的名称。编译器必须理解给定的依赖名称是类型还是变量。它实际上依赖于编译器。为了帮助编译器,您添加了"typename"来表示这个标识符是一个类型。

假设您的代码没有#include ,而是使用forward声明:namespace std { template > class vector; }

那么编译器不知道类向量中的哪些名称是类型,哪些是成员名称。它只知道vector是一种类型。

例如,在代码typename std::vector m_loops;中,大多数编译器都可以省略typename一词,因为它们知道vector是一种类型。

但是,代码std::vector::const_iterator确实需要typename:for (typename std::vector::const_iterator it = loops().begin(); ...的支持。

希望它有帮助。


与模板一起使用时,我对typename的看法是,它指定typename关键字后面的标识符是一个类型。结果是,当使用模板并在模板参数中指定类型时,C++知道它是一种类型,并将正确地展开模板。这是一种明确表示模板参数列表中的某个标识符是一个类型(例如类名或内置类型或其他类型)的方法。

在某些情况下,上下文可能不清楚模板参数中指定的类型是一个类型,因此使用typename使其明确。

例如,请参阅维基百科关于typename的文章

这篇文章也有助于C++中的模板和类型名称关键字。


在您展示的代码中,typenameclass的同义词。这意味着参数是一个类型。

然而,它在其他情况下也有其他用途。每当T1依赖于一个模板参数,而您想要引用T1::T2时,您必须说typename T1::T2而不是让编译器知道T2是一个类型,否则它被视为一个函数或变量。