【问题标题】:C++ argument pack recursion with two arguments带有两个参数的 C++ 参数包递归
【发布时间】:2020-08-06 10:45:19
【问题描述】:

我有一个使用两种类型的模板类:

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&lt;Others&gt; 需要两个参数。

class Foo有多个模板参数时是否可以实现参数包转发?

【问题讨论】:

  • 基本上你必须有偶数个参数在包中,并且必须使用它们来推导函数参数。这对于 C++20 的概念可能直接可行(必须考虑一下),但对于 C++17 及更早版本,需要使用多个间接方法,也许还有一些辅助类和函数。现在究竟你打算在函数本身中对模板参数做什么?这个扣款还需要吗?
  • 我很确定它是重复的 - 我应该将另一个问题保存在书签中。如果是这样的话,一小时后会回来标记它。
  • 不,不应该是Foo&lt;Others...&gt;,因为Foo正好有两个模板参数。
  • 抱歉,误读了问题。两次。
  • 这里的目标是什么?是 `getSize( Foo*, Foo*, Foo*) 吗?

标签: c++ templates variadic-templates template-argument-deduction


【解决方案1】:

你的错误是Foo&lt;Others&gt;*... o 参数。 为模板包 A, B, C, D, E 解包该参数将产生尽可能多的 o 参数:Foo&lt;A&gt;, Foo&lt;B&gt;, Foo&lt;C&gt;, ...

在我看来,如果你只是将你的参数声明为 Other 并让递归失败,如果它们以后不匹配任何 Foo 实例化,会更简单:

template <typename T1, typename T2, typename... Others> size_t getSize(Foo<T1,T2> *f, Others... *o) { ... };

这里,包中的每个Others 类型都会被推导出为你传递的类型。如果您递归调用 getSize 并减少参数数量,它们最终将与 Foo&lt;T1,T2&gt; 参数匹配:

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(/* ... */)

【讨论】:

    【解决方案2】:

    怎么样

    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

    【讨论】:

    • 有效!不知道您可以使用多个 arg 包。
    • @dexter - 新人低估了 dar 的力量......嗯......我的意思是......可变参数模板的变态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 2014-01-15
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多