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.