简体   繁体   English

使用模板时应该何时使用关键字“typename”

[英]When should I use the keyword "typename" when using templates

I've been working lately on a small project, and I couldn't figure out something..我最近一直在做一个小项目,我无法弄清楚一些事情..

I've been given a .h file that was containing a class, using a typename template.我得到了一个包含类的 .h 文件,使用了 typename 模板。 Inside that class there was a private class.在那个班级里面有一个私人班级。

template <typename T>
class Something
{
public:
        Something();
        ~Something();

        Node* Function1(int index);
        int Index(const T& id);


private:
        class Node()
        {
                public:
                T id;

                //Imagine the rest for the Node


        };      
};

The problem occured when I wanted to define the functions of the class "Something"当我想定义“Something”类的函数时出现问题

Here's how I was doing it (in a .inl file)这是我的工作方式(在 .inl 文件中)

template<typename T>
Node* Something::Function1(int index) //Is the return type well written?
{
        // returns the node at the specified index
}

template<typename T>
int Something::Index(const T& id) //Is the parameter type well specified?
{
        // returns the index of the node with the specified id
}

So the bugging part was in the definitions part... Do I have to tell the compiler that the return type (in this case Node*) uses the typename template (like this: typename Node* ) ?所以窃听部分是在定义部分......我是否必须告诉编译器返回类型(在这种情况下 Node*)使用 typename 模板(像这样: typename Node* )? And what about the parameter ?那么参数呢? typename const Node& ? typename const Node& ?

So basically, when do I have to specify wether the function/parameter uses a template?所以基本上,我什么时候必须指定函数/参数是否使用模板?

Thanks for your time.谢谢你的时间。

For Function1 , you need to tell the compiler what Node is -- in this case, it's a nested type inside Something<T> .对于Function1 ,您需要告诉编译器 Node 是什么——在这种情况下,它是Something<T>的嵌套类型。 Because it's dependent on T (it's a dependent name), you need to tell the compiler it's a type, so you must write it as typename Something<T>::Node .因为它依赖于T (它是一个依赖名称),你需要告诉编译器它是一个类型,所以你必须把它写成typename Something<T>::Node The issue is that there might be some T for which Something<T>::Node isn't actually a type (ie if you partially specialize Something<T> ).问题是可能存在一些T ,其中Something<T>::Node实际上不是一种类型(即,如果您部分专门化Something<T> )。

For Index , what you have is fine -- const T& is just a reference to a const T , and the compiler knows what T is.对于Index ,你所拥有的很好—— const T&只是对const T的引用,编译器知道T是什么。

The simple rule: You need to use the typename keyword every time you name a type using the Class::Type syntax, if the Class part depends on a template parameter.简单规则:如果Class部分依赖于模板参数,则每次使用Class::Type语法命名类型时都需要使用typename关键字。 (The Class part might be a template parameter, or it might be a typedef in your class template, etc.) Class部分可能是模板参数,也可能是类模板中的typedef等)

Edit: There's also some confusion about nested class scoping rules.编辑:关于嵌套类范围规则也有一些混淆。 This is mostly independent of the typename issue, so here's a non-template example.这主要与typename问题无关,因此这是一个非模板示例。

class Outer {
public:
  class Inner {
  };
  Inner* func(Inner* obj);
};

Outer::Inner* func(Inner* obj)
{
}

The full name of Inner is Outer::Inner . Inner的全称是Outer::Inner But you can also use the shorter name Inner anywhere from the scope of class Outer , including all of the declaration of func .但是您也可以在类Outer范围Inner任何地方使用较短的名称Inner ,包括func所有声明。 At the definition of func , the return type is NOT in the scope of Outer , so the full name is necessary.func的定义中,返回类型不在Outer的范围内,因此需要全名。 But after the ( , the function parameters ARE in the scope of Outer , so the short name is okay.但是在( ,函数参数在Outer的范围内,所以短名称是可以的。

Combining this with the template-ness of the original example, since the equivalent of Outer is Something<T> , you need the typename keyword to say Something<T>::Node .将其与原始示例的模板性相结合,因为Outer的等价物是Something<T> ,所以您需要typename关键字来表达Something<T>::Node

template<typename T>
typename Something<T>::Node * Something::Function1(int index) //Is the return type well written?
{
        // returns the node at the specified index
}

typename and class are equivalent in template type parameter list: typenameclass在模板类型参数列表中是等效的:

template <class T> class C;

is the same as是相同的

template <typename T> class C;

Where the typename is required is when referring to dependent names :在引用依赖名称时需要typename地方:

template <typename T> struct A {
    typedef typename T::some_type container;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 模板中的关键字“ typename” - Keyword “typename” in Templates 我们可以在没有模板的情况下使用 C++ 关键字“typename”吗? - can we use the C++ keyword “typename” without templates? 我应该何时使用模板以及何时重载函数? - When should I use templates and when overloaded functions? 当使用模板支持functor作为参数时,我应该使用什么限定符? - When using templates to support functor as arguments, what qualifier should I use? 我什么时候应该在 C++ 中使用 new 关键字? - When should I use the new keyword in C++? 定义地图数据时的typename,它是一个带有模板的函数指针 - typename when defining map data that is a function pointer with a sprinkling of templates 将typename关键字与typedef和new一起使用 - Use of typename keyword with typedef and new 在不需要时使用“template”和“typename”消歧器 - Using “template” and “typename” disambiguators when they are not needed 当我需要专用于在模板类中声明的类型名称时,必须使用哪些参数? - When I need to specialize the typename I declared in my template class, what arguments I must use? 当我尝试在模板化 function 中使用迭代器时,“期望在 'typename' 之后有一个限定名称” - “expected a qualified name after 'typename'” when I try to use iterator inside of a templated function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM