我有一个模板类,它使用两种类型:
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) { ... };
如果我只使用一个模板参数实现类foo
,那么它工作得很好。 但是如果有两个(或更多)参数,编译器会抱怨foo
需要两个参数。
当类foo
具有多个模板参数时,是否可能实现参数包转发?
您的错误是foo
参数。 解压缩模板包a,B,C,D,e
的参数将得到同样多的o
参数:foo,foo,foo
。
在我看来,如果您只将参数声明为other
,如果它们与以后的任何foo
实例化不匹配,则让递归失败,这样会更简单:
template <typename T1, typename T2, typename... Others> size_t getSize(Foo<T1,T2> *f, Others... *o) { ... };
在这里,包中的每个others
类型将被推导为您传递的类型。 如果递归调用getSize
并减少参数数量,则它们最终都将与foo
参数匹配:
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(/* ... */)
怎么样
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)
{ /* ... */ }
如果您希望第一个foo
以不同方式进行管理。