namespace std {
template <class R, class F, class... ArgsTypes>
struct is_nothrow_invocable_r;
template <class R, class F, class... ArgsTypes>
inline constexpr bool is_nothrow_invocable_r_v
= std::is_nothrow_invocable_r<R, F, ArgsTypes...>::value;
}
概要
型F
が、与えられた型の引数ArgsTypes...
で関数呼び出し可能であり、その戻り値型がR
に変換可能かつ、その際に例外を投げないかどうかを調べる。
要件
型R, F
およびArgsTypes...
パラメータパックの全ての型が、完全型であること。もしくはconst
/volatile
修飾された(あるいはされていない)void
か、要素数不明の配列型であること。
効果
型F
に対して引数ArgsTypes...
によるINVOKE要件に従った呼び出しが可能であり、その結果となる戻り値の型がR
に変換可能かつ、その呼び出し及び変換に際していかなる例外も投げない場合true_type
から派生し、そうでなければfalse_type
から派生する。
例
#include <type_traits>
#include <iostream>
auto f(int) noexcept -> double {
return 0.0;
}
auto g(double) -> double {
return 0.0;
}
struct from_int {
int n;
operator int() noexcept {
return n;
}
operator double() {
return static_cast<double>(n);
}
};
auto h(int n) noexcept -> from_int {
return from_int{n};
}
int main()
{
std::cout << std::boolalpha;
//f(int) noexcept -> double
std::cout << std::is_nothrow_invocable_r<double, decltype(f), int>::value << std::endl;
//f(int) noexcept -> double (戻り値型変換不可)
std::cout << std::is_nothrow_invocable_r<char*, decltype(f), int>::value << std::endl;
//g(double) -> double (noexceptなし)
std::cout << std::is_nothrow_invocable_r<double, decltype(g), double>::value << std::endl;
//h(int) noexcept -> from_int::operator int() noexcept -> int
std::cout << std::is_nothrow_invocable_r<int, decltype(h), int>::value << std::endl;
//h(int) noexcept -> from_int::operator double() -> double (doubleへの変換演算子にnoexceptなし)
std::cout << std::is_nothrow_invocable_r<double, decltype(h), int>::value << std::endl;
}
出力
true
false
false
true
false
バージョン
言語
- C++17
処理系
- Clang: ??
- GCC: ??
- Visual C++: 2017 Update 3 ✅