# std::make_from_tuple

< cpp‎ | utility

定义于头文件 `<tuple>` |  |
template <class T, class Tuple> constexpr T make_from_tuple(Tuple&& t); |  | (C++17 起)

构造 `T` 类型对象，以元组 `t` 的元素为构造函数的参数。

### 参数

t | - | 元组，其元素被用作 `T` 构造函数的参数

### 返回值

被构造的 `T` 对象。

### 注解

元组不必是 std::tuple ，可以为任何支持 std::get 和 std::tuple_size 的类型所替代；特别是可以用 std::array 和 std::pair 。

因为受保证的复制消除，不需要 `T` 为可移动。

### 可能的实现

    namespace detail {
    template <class T, class Tuple, std::size_t... I>
    constexpr T make_from_tuple_impl( Tuple&& t, std::index_sequence<I...> )
    {
        static_assert(std::is_constructible_v<T,
            decltype(std::get<I>(std::declval<Tuple>()))...>);
        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_v<std::remove_reference_t<Tuple>>>{});
    }

### 示例

    #include <iostream>
    #include <tuple>

    struct Foo {
        Foo(int first, float second, int third) {
            std::cout << first << ", " << second << ", " << third << "\n";
        }
    };

    int main()
    {
       auto tuple = std::make_tuple(42, 3.14f, 0);
       std::make_from_tuple<Foo>(std::move(tuple));
    }

输出：

    42, 3.14, 0

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 3528 | C++17 | 在 1-元组的情况下允许含有 reinterpret_cast 等的转型 | 不允许

### 参阅

make_tuple | 创建一个 `tuple` 对象，其类型根据各实参类型定义 (函数模板)
forward_as_tuple | 创建转发引用的 `tuple` (函数模板)
apply (C++17) | 以一个实参的元组来调用函数 (函数模板)