2017-01-03 112 views
3

我想传递多个参数以便在函数内部构造两个对象,与std::pair<T1, T2>(std::piecewise_construct, ...)工作方式相同。std :: forward_as_tuple将参数传递给2个构造函数

所以我写了

template <typename Args0..., typename Args1...> 
void f(std::tuple<Arg0> args0, std::tuple<Args1> args1) { 
    Object0 alpha(...); 
    Object1 beta(...); 
    ... 
} 

所以我可以调用

f(std::forward_as_tuple(..., ..., ...), std::forward_as_tuple(..., ...)) 

但我不知道如何构建Object0Object1。我检查了我的标准库的源代码std::pair,它们似乎使用复杂的内部函数来获取args0和args1的索引。你有什么想法如何做到这一点?

回答

3

为此,C++ 17将有make_from_tuple,但您可以在C++ 11中编写它。这里是从cppreference中盗取的C++ 14版本(对于C++ 11,您可以使用从Implementation C++14 make_integer_sequence执行std::index_sequence)。

namespace detail { 
template <class T, class Tuple, std::size_t... I> 
constexpr T make_from_tuple_impl(Tuple&& t, std::index_sequence<I...>) 
{ 
    return T(std::get<I>(std::forward<Tuple>(t))...); 
} 
} // namespace detail 

template <class T, class Tuple> 
constexpr T make_from_tuple(Tuple&& t) 
{ 
    return detail::make_from_tuple_impl<T>(std::forward<Tuple>(t), 
     std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{}); 
} 

有了这个工具,的f实施是一件轻而易举的:

template <typename... Args0, typename... Args1> 
void f(std::tuple<Args0...> args0, std::tuple<Args1...> args1) { 
    auto alpha = make_from_tuple<Object0>(args0); 
    auto beta = make_from_tuple<Object1>(args1); 
} 

为了使它更通用的,我建议你只是推断类型的元组和完美转发他们:

template <typename T0, typename T1> 
void f(T0&& args0, T1&& args1) { 
    auto alpha = make_from_tuple<Object0>(std::forward<T0>(args0)); 
    auto beta = make_from_tuple<Object1>(std::forward<T1>(args1)); 
} 

Live C++11 demo

+0

感谢。不幸的是,我需要与RHEL 7提供的gcc 4.8.5兼容。所以我猜,我需要在C++ 11中实现make_index_sequence,这正是我在std :: pair的标准库中找到的。 – InsideLoop

+0

@InsideLoop酷,我添加了一个在C++ 11工作的现场演示。 – TartanLlama

+0

很酷。它适用于gcc 4.8.5 :-) – InsideLoop

相关问题