我有一个可变参数模板函数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时如何正确指定?
答案 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。
在c++20中,我们可以做到
template<class...Args1>
auto G() {
return []<class...Args2>() {
F<Args1...>( obj_1 );
F<Args2...>( obj_2 );
};
}
现在称这是 big 丑陋的。
G<int>().operator()<double, char>();
我们可以使用...标签对此进行清理。这也只需要c++14:
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>);
这很有趣。