2017-01-03 184 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

相關問題