我目前正在编写一些BST模板类作为执行 但我遇到的一个问题让我很困惑。
这是我在头文件中编写的代码 我只粘贴导致错误的部分
template<typename Type>
class TestCls
{
struct Node
{
Type data;
Node* LeftChild;
Node* RightChild;
};
Node* pRoot;
public:
Node* GetNode(Node*& someroot);
};
template<typename Type>
Node * TestCls<Type>::GetNode(Node*& someroot)
{
return NULL;
}
我使用VS2015编译它,然后错误如下:
错误C2059语法错误:&#39;&#39;
错误C2923&#39; TestCls&#39;:&#39;输入&#39;不是参数&#39; Type&#39;
的有效模板类型参数
错误C2923&#39; TestCls&#39;:&#39;输入&#39;不是参数&#39; Type&#39;
的有效模板类型参数
错误C2065&#39;键入&#39;:未声明的标识符
错误C2065&#39;输入&#39;:未声明的标识符
似乎&#39; Node *
&#39;在GetNode()
函数的定义的头部,编译器无法识别。
但是,如果我使用这样的自动返回类型:
auto TestCls<Type>::GetNode(Node*& someroot)->Node*&
{
return NULL;
}
代码将成功编译。
那么第一个版本有什么问题? 我如何正确使用嵌套的struct / class类型作为返回值?
答案 0 :(得分:4)
template<typename Type>
typename TestCls<Type>::Node * TestCls<Type>::GetNode(Node*& someroot)
Node
的范围在类模板中。需要typename
,因为它是一种取决于Type
参数的类型。使用尾随返回类型的情况可以避免这种情况,因为它会在您Node
中指定的范围内查找TestCls<Type>::GetNode
。
答案 1 :(得分:1)
问题是当你写
时template<typename Type>
Node * TestCls<Type>::GetNode(Node*& someroot)
{
return NULL;
}
什么是之前方法的名称(GetNode
)超出了类的名称解析范围。所以你必须明确它
template<typename Type>
typename TestCls<Type>::Node * TestCls<Type>::GetNode(Node*& someroot)
{
return NULL;
}
但是,如果我像这样使用自动返回类型[...]代码将被成功编译。
完全。
由于使用auto
,您在方法名称后面写Node
,因此您可以在类的范围解析中进行操作,因此无需明确它。