C++模板类T的麻烦
template <class T>
class List
{
public:
List();
~List();
...
protected:
template <class T> struct Item
{
struct Item* next;
T data;
};
...
struct Item<T>* allocate();
};
template <class T>
struct Item<T>* List<T>::allocate() // error here
{
...
return object; // struct Item<T>*
}
我怎样才能做到这一点?
template <class T>
class List
{
public:
List();
~List();
...
protected:
template <class T> struct Item
{
struct Item* next;
T data;
};
...
struct Item<T>* allocate();
};
template <class T>
struct Item<T>* List<T>::allocate() // error here
{
...
return object; // struct Item<T>*
}
how can i do that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您正在重复使用
T
类型名称。使用不同的:模板struct Item { ...
(或从Item
中删除模板化 - 看起来您对外部模板参数很好):You are reusing the
T
type name. Use a different one:template <class U> struct Item { ...
(or remove templatization fromItem
all together - it looks like you are just fine with outer template parameter):方法定义的正确语法是出于某种原因,其他发布者坚持将
部分附加到Item
而不是List
(显然是被你的原始版本欺骗了)。抱歉,我没有注意到
Item
本身也是一个模板。在这种情况下,它必须是但是,请注意,在内部模板声明中重复使用相同的参数名称是非法的!你原来的类定义是非法的。它必须改为类似的东西
The correct syntax for method definition isFor some reason other posters insisted on attaching the
<T>
part toItem
instead ofList
(tricked by your original version, apparently).Sorry, I haven't noticed that
Item
is also a tempate by itself. In that case it has to beHowever, note that it is illegal to re-use the same parameter name in the inner template declaration!!! Your original class definition is illegal. It has to be changed to something like
写入:::
运算符告诉编译器 Item 是 List 的嵌套类。
Write:
The :: operator tells the compiler that Item is a nested class of List.
事实上,问题更深层:
您不必将
Item
声明为template
,因为它是模板类中的嵌套类,它可以访问T
。然后你可以像这样定义
access
:这里的要点是
List
是一个模板类,所以它的参数必须指定,而一旦T
> 是为List
指定的,无需再次精确。注意
类型名称
;)The problem is deeper in fact:
You don't have to declare
Item
as beingtemplate
, because it's a nested class within a template class it has access toT
.And then you would define
access
like so:The point here is that
List
is a template class, so its parameters must be specified, while onceT
is specified forList
it's not necessary to precise it once again.Note
typename
;)您需要限定类型:
List::Item
。当您位于类声明内部或该类型(或派生类)的每个成员函数的参数列表或主体内时,可以使用该类型的非限定名称,但不能用于返回类型。当编译器解析返回类型时,它还不知道您正在定义
List
模板的成员,因此它不会在该类范围内查找。这是编译器工作方式的一个有趣的点,它实际上影响了即将发布的标准中的一些更改,以允许像返回类型定义一样的 auto :
编译器能够推导出类型 T 和
U
一旦参数存在,但你不能告诉它返回类型是decltype(lhs+rhs)
作为返回类型,因为lhs
rhs
都尚未在范围内。虽然这只是 C++ 的问题,但它的根源与您面临的问题相同:返回类型的范围位于所声明的方法的范围之外。You need to qualify the type:
List::Item<T>
.You can use the non-qualified name of the type when you are inside the class declaration, or inside the argument list or body of each of the member functions of the type (or derived classes), but not for the return type. When the compiler resolves the return type, it does not yet know that you are defining a member of the
List
template, and as such it will not look inside that class scope.This is an interesting point of how compilers work that has actually influenced some changes in the upcoming standard to allow
auto
like return type definitions:The compiler is able to deduce types
T
andU
once the arguments are present, but you cannot tell it that the return type isdecltype(lhs+rhs)
as return type since neitherlhs
norrhs
are yet in scope. While this is a C++ only problem, it has its roots in the same problem you are facing: the scope of the return type is external to the scope of the method that is being declared.