4294967295
4294967295

Reputation: 11

need to return the same type as this from c++ template function

I want a template function to return the same type as this. It is easy to get the types of arguments in parens, but I do not see how to get the type of the object whose method is called.

struct ENode {
    ENode* mnext;
    ENode(ENode* n):mnext(n){}
    template<typename T>T* next(T* unused) { return (T*)mnext; }
    template<typename T>T* xnext() { return (T*)mnext; }
};

struct TNode : public ENode {
    int val;
    TNode(int v, TNode* n):val(v),ENode(n){}
};

void printTN(TNode* n) {
    while(n) {
    printf("%i -> ", n->val);
//  n=n->next(n); // ok, but n is unused
//  n=n->xnext(); // error: template argument deduction/substitution failed:  couldn't deduce template parameter ‘T’
//  n=n->xnext<std::remove_reference<decltype(*n)>::type>(); // works, but is very ugly
    n=n->xnext<TNode>(); // works, but is ugly
    }
    printf("nil\n");
}

How do I have n->next() return the same type as n?

EDIT As to Template deduction for function based on its return type? , it would help me if it was possible. But there is no overload or type deduction on the return type in C++ (unlike Java). Therefore I want an overload on the type of *this.

Upvotes: 1

Views: 775

Answers (2)

If you don't mind the slight change in syntax, one possibility is to make next a free function template:

struct ENode {
    ENode* mnext;
    ENode(ENode* n):mnext(n){}
    template<typename T> friend T* next(T *self) { return static_cast<T*>(self->mnext); }
};

struct TNode : public ENode {
    int val;
    TNode(int v, TNode* n):val(v),ENode(n){}
};

void printTN(TNode* n) {
    while(n) {
      printf("%i -> ", n->val);
      n = next(n);
    }
    printf("nil\n");
}

Upvotes: 1

Phil M
Phil M

Reputation: 1619

A common pattern is to have the entire ENode class take a template parameter, instead of just the next/xnext methods.

E.g.,

template <typename T> struct ENode {
    ...
    T* next() { return mnext; }
};
struct TNode : ENode<TNode> { ... }

Upvotes: 5

Related Questions