std::is_constructible, std::is_trivially_constructible, std::is_nothrow_constructible
| ヘッダ <type_traits> で定義
|
||
template< class T, class... Args > struct is_constructible; |
(1) | (C++11以上) |
template< class T, class... Args > struct is_trivially_constructible; |
(2) | (C++11以上) |
template< class T, class... Args > struct is_nothrow_constructible; |
(3) | (C++11以上) |
1) T がオブジェクトまたは参照型で、変数定義 T obj(std::declval<Args>()...); が well-formed であれば、 true に等しいメンバ定数 value が提供されます。 そうでなければ、 value は false です。
この確認の目的に対しては、変数定義は関数宣言と解釈されることはなく、 std::declval の使用が ODR-使用とみなされることもありません。 アクセスチェックは T や Args のいずれの型とも無関係の文脈で行われたかのように行われます。 変数定義の直接の文脈の有効性のみが考慮されます。
2) 1) と同じですが、変数定義はトリビアルでないいかなる操作も呼び出しません。 この確認の目的に対しては、 std::declval の呼び出しはトリビアルとみなされます。
3) 1) と同じですが、変数定義は noexcept になります。
T およびパラメータパック Args 内のすべての型 はいずれも完全型 (またはその cv 修飾された型)、 void、またはサイズの未知な配列でなければなりません。 そうでなければ、動作は未定義です。
上記のテンプレートの実体化が直接または間接的に不完全型に依存しており、もしその型が仮に完全型であったならばその実体化が異なる結果を産むであろう場合は、動作は未定義です。
ヘルパー変数テンプレート
<tbody> </tbody> template< class T, class... Args > inline constexpr bool is_constructible_v = is_constructible<T, Args...>::value; |
(C++17以上) | |
template< class T, class... Args > inline constexpr bool is_trivially_constructible_v = is_trivially_constructible<T, Args...>::value; |
(C++17以上) | |
template< class T, class... Args > inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<T, Args...>::value; |
(C++17以上) | |
std::integral_constant から継承
メンバ定数
value [静的] |
T が Args... から構築可能ならば true、そうでなければ false (パブリック静的メンバ定数) |
メンバ関数
operator bool |
オブジェクトを bool に変換します。 value を返します (パブリックメンバ関数) |
operator() (C++14) |
value を返します (パブリックメンバ関数) |
メンバ型
| 型 | 定義 |
value_type
|
bool
|
type
|
std::integral_constant<bool, value>
|
ノート
多くの処理系では、 is_nothrow_constructible は、実質的に noexcept(T(arg)) であるため、デストラクタが例外を投げるかどうかも確認します。 同じことが is_trivially_constructible にも適用され、これらの処理系では、デストラクタがトリビアルであることも要求されます。 GCC bug 51452 や LWG issue 2116 も参照してください。
例
#include <iostream>
#include <type_traits>
class Foo {
int v1;
double v2;
public:
Foo(int n) : v1(n), v2() {}
Foo(int n, double f) noexcept : v1(n), v2(f) {}
};
int main() {
std::cout << "Foo is ...\n" << std::boolalpha
<< "\tTrivially-constructible from const Foo&? "
<< std::is_trivially_constructible<Foo, const Foo&>::value << '\n'
<< "\tTrivially-constructible from int? "
<< std::is_trivially_constructible<Foo, int>::value << '\n'
<< "\tConstructible from int? "
<< std::is_constructible<Foo, int>::value << '\n'
<< "\tNothrow-constructible from int? "
<< std::is_nothrow_constructible<Foo, int>::value << '\n'
<< "\tNothrow-constructible from int and double? "
<< std::is_nothrow_constructible<Foo, int, double>::value << '\n';
}
出力:
Foo is ...
Trivially-constructible from const Foo&? true
Trivially-constructible from int? false
Constructible from int? true
Nothrow-constructible from int? false
Nothrow-constructible from int and double? true
関連項目
| 型がデフォルトコンストラクタを持っているかどうか調べます (クラステンプレート) | |
(C++11)(C++11)(C++11) |
型がコピーコンストラクタを持っているかどうか調べます (クラステンプレート) |
(C++11)(C++11)(C++11) |
型が右辺値参照から構築できるかどうか調べます (クラステンプレート) |