Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write a member function that returns a type that only exists in the class?

Tags:

c++

list

I'm actually implementing a doubly-linked list in C++.

Here's a MWE of sorts:

namespace mynamespace {

template <typename T>
class List {
public:
    List();

    void prepend(T);
    void append(T);
    void remove(T);

private:
    struct Node {
        T value_;
        Node * prev_;
        Node * next_;
    };

private:
    Node * find(T); // <-- THIS IS MY PROBLEM

private:
    Node * head_;
    Node * tail_;
};

}

The reason I'd like to create that function is because I figured it'd be handy if I could traverse the list with a function like that until I find a given element (I'll need to do the same with the remove() function anyways)

But how do I define that function outside the class definition?

Since Node is a private member of the List class, this is not working:

template <typename T>
Node * List<T>::find(T val)
{
    // stuff
}

I suppose defining the function inside the class definition would work, because Node makes sense there... Would that be the proper way? Even if so, I suppose there must be a way to define the function the way I'm trying to...

like image 765
bp99 Avatar asked Apr 05 '18 17:04

bp99


1 Answers

Since Node is a private member of the List class, this is not working:

Actually, that's not correct. It's not failing because Node is private, but because Node is nested inside of List. The name of the Node class isn't Node, it's List<T>::Node. However, since Node depends on T, you have to write typename List<T>::Node, otherwise the compiler assumes that List<T>::Node is a value rather than a type. See this question for more information.

In short, replace this:

template <typename T>
Node * List<T>::find(T val)

With this:

template <typename T>
typename List<T>::Node * List<T>::find(T val)

Alternatively, as StoryTeller noted, if you are in the context of the List<T> class, you can just use Node. You can get in this context by using a trailing return type:

template <typename T>
auto List<T>::find(T val) -> Node *
like image 153
Justin Avatar answered Oct 19 '22 01:10

Justin