我最近一直在做一个小项目,我无法弄明白......
我使用typename模板获得了一个包含类的.h文件。在那堂课里面有一个私人课程。
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
};
};
当我想定义类“Something”
的功能时出现问题我是这样做的(在.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 :(得分:5)
对于Function1
,您需要告诉编译器Node是什么 - 在这种情况下,它是Something<T>
内的嵌套类型。因为它依赖于T
(它是一个从属名称),所以你需要告诉编译器它是一个类型,所以你必须把它写成typename Something<T>::Node
。问题是可能有T
Something<T>::Node
实际上不是Something<T>
类型(即如果您部分专门化Index
)。
对于const T&
,你所拥有的很好 - const T
只是对T
的引用,编译器知道{{1}}是什么。
答案 1 :(得分: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
。但您也可以在类Inner
的范围内使用较短的名称Outer
,包括func
的所有声明。在func
的定义中,返回类型不在Outer
的范围内,因此全名是必需的。但是在(
之后,函数参数在Outer
的范围内,所以短名称是可以的。
将此与原始示例的模板相结合,因为Outer
的等效值为Something<T>
,您需要使用typename
关键字来说明Something<T>::Node
。
答案 2 :(得分: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
}
答案 3 :(得分:1)
typename
和class
在模板类型参数列表中是等效的:
template <class T> class C;
与
相同template <typename T> class C;
需要typename
的地方是指dependent names:
template <typename T> struct A {
typedef typename T::some_type container;
};