我有一个模板类,它使用两种类型:
template<typename T1,typename T2> class Foo { ... };
我需要写一个函数,它接受任意数量的Foo
变量:
template <typename T1, typename T2, typename... Others> size_t getSize(Foo<T1,T2> *f, Foo<Others>*... o) { ... };
如果我只使用一个模板参数来实现class Foo
,它工作得很好。但是对于两个(或更多(参数,编译器会抱怨Foo<Others>
需要两个参数。
当class Foo
具有多个模板参数时,是否可以实现参数包转发?
怎么样
template <typename ... Ts1, typename ... Ts2>
std::size_t get_size (Foo<Ts1, Ts2> * ... fs)
{ /* ... */ }
或者,也许,
template <typename T1, typename T2, typename ... Us1, typename ... Us2>
std::size_t get_size (Foo<T1, T2> * f, Foo<Us1, Us2> * ... fs)
{ /* ... */ }
如果您想要以不同方式管理第一个CCD_ 5。
您的错误是Foo<Others>*... o
参数。为模板包A, B, C, D, E
解包该参数会得到尽可能多的o
参数:Foo<A>, Foo<B>, Foo<C>, ...
。
在我看来,如果你只是将你的参数声明为Other
,并让递归失败,如果它们稍后与任何Foo
实例化都不匹配,那会更简单:
template <typename T1, typename T2, typename... Others> size_t getSize(Foo<T1,T2> *f, Others... *o) { ... };
这里,包中的每个Others
类型都将被推导为您传递的类型。如果您递归调用getSize
并减少参数数量,它们最终都将与Foo<T1,T2>
参数匹配:
return f->size()
+ getSize(std::forward<Others>(o)...); // the first argument in the pack will
// be Foo<T3,T4> type
// or the compilation will fail
你也可以添加一个类型特征来直接进行检查:
template <class T> struct IsFoo : std::false_type {};
template <class T, class U> struct IsFoo<Foo<T,U>> : std::true_type {};
template </* ... */>
std::enable_if_t<std::conjunction<IsFoo<Others>::value...>::value, size_t> getSize(/* ... */)