Variadic template base class call forwarding

c++, c++11, templates, variadic-templates

Solution

This should work:

template<typename F, typename... T>
    struct recinit;

template<typename F>
    struct recinit<F> {
        static bool tinit(F *) {
            return true;
        }
    };
template<typename F, typename T, typename... G>
    struct recinit<F, T, G...> {
        static bool tinit(F *ptr)  {
            if (!ptr->T::init())
                return false;
            return recinit<F, G...>::tinit(ptr);
        }
    };

template<typename... Features>
struct Foo : Features... {

    bool init() {
        bool res = recinit<Foo, Features...>::tinit(this);
        //use res wisely
    }
};

Your problem is that you cannot write partial specializations of functions, only of classes/structs. And the auxiliary struct has to be outside of `Foo` or else it will get the template arguments from the enclosing struct, and that would be bad.

You don't say but I'm assuming that `init` is a non-static member function. If that is the case, the `args` arguments make little sense: all of them should be `this`! So just past this once and avoid the pack in the arguments. I tried passing `this` as a `void*` but that may be troublesome, so I just added an additional template argument to `recinit` that will be `Foo`.

And also, each time you do one recursive step remember to remove one parameter.

Problem

In pre-11 C++ I had something like this: ``` template<class T,class U,class V> struct Foo : T,U,V { bool init() { if(!T::init() || !U::init() || !V::init()) return false; // do local init and return true/false } }; ``` I'd like to convert this to C++11 variadic syntax to get the benefit of the flexible length argument list. I understand the concept of unpacking the template arg list using recursion but I just can't seen to get the syntax right. Here's what I've tried: ``` template<typename... Features> struct Foo : Features... { template<typename F,typename... G> bool recinit(F& arg,G&& ...args) { if(!F::init()) return false; return recinit<F,G...>(args...); } bool init() { // how to call recinit() from here? } }; ``` I would prefer the order of the calls to the base class init() functions to be left-to-right but it's not critical.

Original source

Related problems