[英]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: typename
和class
在模板类型参数列表中是等效的:
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.