两包可变参数模板参数

时间:2019-03-04 20:14:19

标签: c++ variadic-templates

我有一个可变参数模板函数F,必须精确地在两个对象上调用它。因此,另一个名为G的函数将调用F两次,一次对对象1调用,另一个对对象2调用。因此,G也是可变参数,但是问题在于,对F的两次调用的两个可变参数包可能是不同的,并且G必须知道哪个对对象1进行调用,对哪个对象2进行调用:

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时如何正确指定?

2 个答案:

答案 0 :(得分:3)

在这里使用Tag可能会有所帮助,因为您无法部分专门化功能:

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 );
}

答案 1 :(得分:1)

标记是一个不错的计划。如果您不想使用标签,则可以使用lambda。

中,我们可以做到

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

现在称这是 big 丑陋的。

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>);

这很有趣。