Search code examples
c++inheritancemetaprogrammingbase-classtemplate-classes

Simpler Method for Getting the Base Class


OK so I was cooking up an answer here which has more detail (and a better alternative.) But I realized I'd made a couple template functions which had a lot of redudancy. Given:

template<typename T>
struct Parent {};

struct Child : Parent<int> {};

I wrote the following template functions for getting the appropriate Parent pointer:

namespace details {
    template<typename T>
    Parent<T>* make_parent(Parent<T>* param) { return param; }
}

template<typename T>
auto make_parent(T& param) -> decltype(details::make_parent(&param)) { return details::make_parent(&param); }

There seems to be a lot of repetition in there. But I can't figure out how to make it cleaner. Can I combine this into a single function without it looking like a nightmare?

EDIT:

My intention is that I can do:

Child foo;
auto bar = make_parent(foo);

(As opposed to the easier version in the other answer, where I pass a pointer.)


Solution

  • All of this can be simplified to

    template<typename T>
    Parent<T>* get_parent_ptr(Parent<T>& param) { return &param; }
    

    This will give you the pointer to the Parent part of anything derived from Parent

    If you want to be able to handle const objects as well, and prevent getting a pointer to a temporary, unfortunately you will have to add a little more by adding

    template<typename T>
    const Parent<T>* get_parent_ptr(const Parent<T>& param) { return &param; }
    
    template<typename T>
    Parent<T>* get_parent_ptr(Parent<T>&& param) = delete; // if you don't care about getting a pointer to a rvalue you can remove this
    

    You can see all of this working with this live example:

    int main()
    {
        Child c;
        auto cp = get_parent_ptr(c);
        const Child cc;
        auto ccp = get_parent_ptr(cc);
        //auto error = get_parent_ptr(Child{});
    }
    

    If you uncomment the error line you will get and error that you are trying to use a deleted function.