在11 C之前我有这样的事情:
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 } };
我想将其转换为C 11可变参数语法,以获得灵活长度参数列表的好处.我理解使用递归解压缩模板arg列表的概念,但我无法看到正确的语法.这是我尝试过的:
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? } };
解决方法
这应该工作:
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 } };
你的问题是你不能写函数的部分特化,只能编写类/结构.辅助结构必须在Foo之外,否则它将从封闭结构中获取模板参数,这将是不好的.
你没有说,但我假设init是一个非静态成员函数.如果是这种情况,args参数就没有意义了:所有这些都应该是这样的!所以只要过去一次就可以避免争论中的包装.我尝试将其作为void *传递但是这可能很麻烦,所以我只是添加了一个额外的模板参数来重新定义将是Foo.
而且,每次执行一个递归步骤时,请记住删除一个参数.