namespace std {
template<class F, class Tuple>
constexpr decltype(auto)
apply(F&& f, Tuple&& t); // (1) C++20
template<class F, tuple-like Tuple>
constexpr decltype(auto)
apply(F&& f, Tuple&& t) noexcept(see below); // (1) C++23
}
概要
タプルを展開し、関数の引数に適用してその関数を実行する。
要件
適用先の関数はCallable
要件を満たす(INVOKE操作が可能)。展開されるTuple
型はstd::tuple
に限定されず、std::array
またはstd::pair
のように、std::get
とstd::tuple_size
をサポートする型であればよい。(C++20 まで。)C++23 ではtuple-like
による制約が追加されたため、使用できる型は狭まった。(tuple-like
参照)
効果
次のような関数があるとき、
// C++17
template<class F, class Tuple, size_t... I>
constexpr decltype(auto) apply-impl(F&& f, Tuple&& t, std::index_sequence<I...>) {
return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
}
// C++23
template<class F, tuple-like Tuple, size_t... I>
constexpr decltype(auto) apply-impl(F&& f, Tuple&& t, std::index_sequence<I...>) {
return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
}
C++17 : 次と等価である。
return apply-impl(std::forward<F>(f), std::forward<Tuple>(t),
std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>{});
C++20 : 次と等価である。
return apply-impl(std::forward<F>(f), std::forward<Tuple>(t),
std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
戻り値
適用した関数呼び出しの戻り値
例外
C++23から : I
をパラメータパック0, 1, ..., (tuple_size_v<remove_reference_t<Tuple>>-1)
としたとき、例外指定の式は次と等価 : noexcept(invoke(std::forward<F>(f), get<I>(std::forward<Tuple>(t))...))
例
#include <iostream>
#include <tuple>
#include <string>
void f(int a, double b, std::string c)
{
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
}
int main()
{
std::tuple<int, double, std::string> args(1, 3.14, "hello");
std::apply(f, args);
}
17
#include <iostream>
#include <tuple>
#include <string>
void f(int a, double b, std::string c)
{
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
}
int main()
{
std::tuple<int, double, std::string> args(1, 3.14, "hello");
std::apply(f, args);
}
出力
1
3.14
hello
バージョン
言語
- C++17
処理系
- Clang: 3.9.1 ✅
- GCC: 7.1.0 ✅
- ICC: ??
- Visual C++: ??
関連項目
参照
- N3802
apply()
call a function with arguments from a tuple - N3829
apply()
call a function with arguments from a tuple (V2) - N3915
apply()
call a function with arguments from a tuple (V3) - P0220R0 Adopt Library Fundamentals TS for C++17
- P0220R1 Adopt Library Fundamentals V1 TS Components for C++17 (R1)
- C++1z タプルを展開して関数呼び出しするapply関数 - Faith and Brave - C++で遊ぼう
- P0777R1 Treating Unnecessary
decay
- C++20から効果説明の
decay_t
をremove_cvref_t
へ変更。
- C++20から効果説明の
- P2517R1 Add a conditional
noexcept
specification tostd::apply
- C++23から条件付きで
noexcept
例外指定が行われる。
- C++23から条件付きで