Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a nested struct/class type as a return value, in a template class?

I currently writing some BST template class as execise but a promblem I met confuses me.

Here is my code written in a header file I only paste the part that causes the error here

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;
}

I use VS2015 to compile it, then the errors as below:

Error C2059 syntax error: '' Error C2923 'TestCls': 'Type' is not a valid template type argument for parameter 'Type'
Error C2923 'TestCls': 'Type' is not a valid template type argument for parameter 'Type'
Error C2065 'Type': undeclared identifier
Error C2065 'Type': undeclared identifier

It seems the 'Node *' in the head of the GetNode() function's definition isn't recognized by the compiler.

However if I use auto return type like this:

auto TestCls<Type>::GetNode(Node*& someroot)->Node*&
{
    return NULL;
}

The code will be compiled successfully.

So what's wrong in the first version? How I properly use a nested struct/class type as a return value?

like image 765
LonelySnake Avatar asked Oct 22 '25 04:10

LonelySnake


2 Answers

template<typename Type>
typename TestCls<Type>::Node * TestCls<Type>::GetNode(Node*& someroot)

Node is scoped inside the class template. typename is needed because it is a type that depends on the Type parameter. This is all avoided with the trailing return type case, because it looks up Node in the scope that you already specified in TestCls<Type>::GetNode.

like image 155
Quentin Avatar answered Oct 23 '25 18:10

Quentin


The problem is that when you write

template<typename Type>
Node * TestCls<Type>::GetNode(Node*& someroot)
{
    return NULL;
}

what is before the name of the method (GetNode) is outside the scope of name resolution of the class. So you have to explicit it

template<typename Type>
typename TestCls<Type>::Node * TestCls<Type>::GetNode(Node*& someroot)
{
    return NULL;
}

However if I use auto return type like this [...] The code will be compiled successfully.

Exactly.

Because using auto, you write Node after the name of the method, so you're in scope resolution of the class so there is no need to explicit it.

like image 22
max66 Avatar answered Oct 23 '25 18:10

max66



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!