【问题标题】:std::forward_as_tuple to pass arguments to 2 constructorsstd::forward_as_tuple 将参数传递给 2 个构造函数
【发布时间】:2017-01-03 09:03:46
【问题描述】:

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

所以我写了

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 的索引。你知道怎么做吗?

【问题讨论】:

    标签: c++ c++11 tuples


    【解决方案1】:

    C++17 将有 make_from_tuple 用于执行此操作,但您可以在 C++11 中编写此代码。这是从 cppreference 窃取的 C++14 版本(对于 C++11,您可以使用来自 Implementation C++14 make_integer_sequencestd::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

    【讨论】:

    • 谢谢。不幸的是,我需要与 RHEL 7 提供的 gcc 4.8.5 兼容。所以我想,我需要在 C++11 中实现 make_index_sequence,这正是我在 std::pair 标准库中找到的。
    • @InsideLoop 酷,我添加了一个使用 C++11 工作的现场演示。
    猜你喜欢
    • 2012-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2023-04-04
    • 2015-10-11
    • 2013-02-20
    相关资源
    最近更新 更多