【问题标题】:Two packs of variadic template arguments两包可变参数模板参数
【发布时间】:2019-03-05 04:42:30
【问题描述】:

我有一个可变参数模板函数 F,它必须恰好被两个对象调用。因此,另一个名为 G 的函数将调用 F 两次,一次用于对象一,另一次用于对象二。因此 G 也是可变参数的,但问题是对 F 的两次调用的两个可变参数包可能不同,并且 G 必须知道哪个调用对象一,哪个调用对象二:

template< typename ...Args>
void F(Obj obj);

template<typename ...Args1, typename ...Args2>
void G(Obj obj_1, Ojb obj_2)
{
    F<Args1...>( obj_1 );
    F<Args2...>( obj_2 );
}

现在如果我调用 G,obj_1 调用哪个版本的 F,obj_2 调用哪个版本?调用G时如何正确指定?

【问题讨论】:

  • 您可以将包包装为元组并转发它们。

标签: c++ variadic-templates


【解决方案1】:

在这里使用标签可能会有所帮助,因为您不能部分专门化功能:

template <typename ... Ts>
struct Tag {};

template< typename ...Args>
void F(Obj obj) { /*...*/ }

template<typename ...Args1, typename ...Args2>
void G(Tag<Args1...>, Obj obj_1, Tag<Args2...>, Ojb obj_2)
{
    F<Args1...>( obj_1 );
    F<Args2...>( obj_2 );
}

【讨论】:

    【解决方案2】:

    标签是一个很棒的计划。如果不想使用标签,可以使用 lambdas。

    在我们可以做

    template<class...Args1>
    auto G() {
      return []<class...Args2>() {
        F<Args1...>( obj_1 );
        F<Args2...>( obj_2 );
      };
    }
    

    现在称这是一个大丑陋的。

    G<int>().operator()<double, char>();
    

    我们可以用 ... 标签来清理它。这也只需要:

    template<class T>
    struct tag_t { using type=T; };
    template<class T>
    constexpr tag_t<T> tag{};
    
    template<class...Args1>
    auto G(tag_t<Args1>...) {
      return [](auto...args2) {
        F<Args1...>( obj_1 );
        F<typename decltype(args2)::type...>( obj_2 );
      };
    }
    

    现在调用它变成:

    G(tag<int>)(tag<double>, tag<char>);
    

    哪个更有趣。

    【讨论】:

      猜你喜欢
      • 2016-12-01
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多