2010-11-19 167 views
3

我一直在一个小项目,最近的工作时,我无法弄清楚的东西我使用关键字“类型名称” ..什么时候应该使用模板

我已经拥有一个.H文件包含一个类,使用一个typename模板。在那个班里面有一个私人班。

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 


     };  
}; 

问题发生时,我想定义(在.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 
} 

所以窃听类的“东西”

以下是我在做它的功能部分在定义部分...我是否必须告诉编译器返回类型(在这种情况下是Node *)使用typename模板(如下所示:typename Node*)?那么参数呢? typename const Node&

所以基本上,我什么时候必须指定更多的功能/参数使用模板?

谢谢你的时间。

+0

请将sinppets发布到您的问题中! – mmmmmmmm 2010-11-19 17:45:09

+0

我已经发布了片段的链接。我无法弄清楚如何正确缩进我的片段。 – Pacane 2010-11-19 17:45:47

回答

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

好的,另一种方法的参数类型呢? – Pacane 2010-11-19 17:48:08

+3

'Node'是一个嵌套的类名。所以你不能使用它,除非你在代码中使用'Something '的方法,或者你使用完整的'typename Something :: Node'名称。而且一个方法返回类型(在类之外定义)还没有在“Something”的方法中,所以你必须向编译器说清楚。另一种方法不会有这样的问题,因为编译器总是知道'int'的含义。 – aschepler 2010-11-19 17:53:45

+0

感谢您的解释,并花时间。 – Pacane 2010-11-19 18:00:54

3

简单的规则:你需要使用typename关键字每次名称中使用Class::Type语法类型,如果Class部分取决于模板参数。 (Class部分可能是模板参数,或者可能是您的班级模板中的typedef等)

编辑:对于嵌套类作用域规则也存在一些困惑。这主要与typename问题无关,所以这里是一个非模板示例。

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

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

Inner全称是Outer::Inner。但是,您也可以使用类别为Outer的范围内的任何地方的简称Inner,其中包括func的所有声明。在func的定义中,返回类型不在Outer的范围内,所以全名是必需的。但在(之后,功能参数ARE在Outer的范围内,所以短名称没问题。

与原来的例子的模板岬结合这一点,因为Outer相当于是Something<T>,你需要的typename关键字说Something<T>::Node

+0

所以参数类型在函数Index的定义中应该写成typename const类 :: Node&id? – Pacane 2010-11-19 17:54:31

+1

@Pacane:这取决于,你想通过一个'T'还是'Node'?如果你确实想传递一个'Node',完整的版本可以工作,但是不需要,因为编译器只是看到你正在定义一个'Something'方法,'const Node&'会很好。 – aschepler 2010-11-19 17:57:37

+0

感谢您的解释,并花时间。 – Pacane 2010-11-19 18:01:47

5

对于Function1,您需要告诉编译器Node是什么 - 在这种情况下,它是Something<T>中的嵌套类型。由于它取决于T(它是一个独立的名称),因此您需要告诉编译器它是一种类型,所以您必须将其编写为typename Something<T>::Node。问题是可能有一些T其中Something<T>::Node实际上不是一种类型(即,如果您部分专门Something<T>)。

对于Index,你有什么好 - const T&只是对const T的引用,编译器知道什么是T

+0

所以如果参数是一个指向节点的指针,我必须再次指定typename部分,对吧? – Pacane 2010-11-19 17:56:44

+1

因为你在'Something '内,所以你可以写'Node *'。但是如果你明确地写出来了,你需要说'typename Something :: Node *',而不仅仅是'Something :: Node *'。 – 2010-11-19 18:01:11

+0

感谢您的解释,并花时间。 – Pacane 2010-11-19 18:02:12

1

typenameclass在模板类型参数列表相当于:

template <class T> class C; 

相同

template <typename T> class C; 

如果要求typename指的是dependent names时:

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

实际上,typename和class在参数列表中并不等价。当期望模板模板参数时,typename关键字不能替换'class'。 – 2010-11-19 18:03:27

+0

是的,谢谢,忘了这个。尽管这只是语言方面的一个嘘声 - 他们只是忘记了这个情况,和我在这里一样:) – 2010-11-19 18:04:06

相关问题