- tuple[meta header]
- function template[meta id-type]
- std[meta namespace]
- cpp17[meta cpp]
namespace std {
template <class T, class Tuple>
constexpr T make_from_tuple(Tuple&& t);
}
tuple-likeな型Tuple
のオブジェクトに含まれる値から型T
のオブジェクトを構築する。
型T
のコンストラクタの内のいずれか一つが、型Tuple
に含まれる全ての型の値をその順番通りに受け入れ可能であること。それができない場合はコンパイルエラーとなる。
また、型T
の初期化はそのコンストラクタで行われ集成体初期化は考慮されない。つまり、Tuple
に含まれる型が空かただ一つのT
でない場合、型T
は集成体(aggregate)であってはならない(C++17のみ、C++20以降はok)。
t
-- tuple-likeな型Tuple
のオブジェクト
tuple-likeな型とは主にstd::tuple
の事であるが、std::pair
やstd::array
のようにstd::tuple
と同じような扱いができる型も含んでいる。
より詳細には、std::get
(インデックス指定)とstd::tuple_size
が適用可能な型である。
Tuple
に含まれる型の値をその順番通りに型T
のコンストラクタにstd::forward
して構築されたT
のオブジェクト。
Tuple
に含まれる型の値を受け取るT
のコンストラクタが例外を送出する可能性がある場合は、この関数も例外を送出しうる。
構築したい型T
は引数からの推論ができないので、明示的に指定する必要がある。
また、値のコピー省略保証に対応するコンパイラであれば型T
はムーブ可能である必要はない(戻り値のT
のオブジェクトは呼び出し元で構築される)。
template<class T, class Tuple, std::size_t... Index>
constexpr T make_from_tuple_impl(Tuple&& t, std::index_sequence<Index...>){
return T(std::get<Index>(std::forward<Tuple>(t))...);
}
template <class T, class Tuple>
constexpr T make_from_tuple(Tuple&& t) {
return make_from_tuple_impl<T>(std::forward<Tuple>(t), std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
}
- std::forward[link /reference/utility/forward.md]
- std::make_index_sequence[link /reference/utility/make_index_sequence.md]
- std::index_sequence[link /reference/utility/index_sequence.md]
- std::decay_t[link /reference/type_traits/decay.md]
#include <tuple>
#include <array>
#include <iostream>
struct sample {
sample(int a, int b, double c, const char* d) {
std::cout << a << ", " << b << ", " << c << ", " << d << std::endl;
}
sample(int a, double b) {
std::cout << a << ", " << b << std::endl;
}
sample(int a1, int a2, int a3, int a4) {
std::cout << a1 << ", " << a2 << ", " << a3 << ", " << a4 << std::endl;
}
//あらゆるムーブ・コピー操作をdelete
sample(sample&&) = delete;
sample(const sample&) = delete;
sample& operator=(sample&&) = delete;
sample& operator=(const sample&) = delete;
};
int main()
{
{
auto t = std::make_tuple(0, 10, 20.0, "Hello world.");
//std::tuple<int, int, double, const char*>からの構築
auto s = std::make_from_tuple<sample>(std::move(t));
}
{
auto p = std::make_pair(30, 40.0);
//std::pair<int, double>からの構築
auto s = std::make_from_tuple<sample>(std::move(p));
}
{
std::array<int, 4> a = {1, 2, 3, 4};
//std::arrayからの構築
auto s = std::make_from_tuple<sample>(std::move(a));
}
}
- std::make_from_tuple[color ff0000]
- std::make_tuple[link ../tuple/make_tuple.md]
0, 10, 20, Hello world.
30, 40
1, 2, 3, 4
- C++17
- Clang: ??
- GCC: ??
- Visual C++: 2017