目的
メタクラスを使って型のコンストラクタ・デストラクタ・代入演算子情報を取得するサンプルコードです。C++20では標準でコピーコンストラクタやムーブコンストラクタが自動作成されるので、確認する方法を準備しておこうと作成しました。
出力例(std::c++latest、C++20 draft)
コード
# include <vector>
# include <iostream>
# include <type_traits>
using namespace std;
// 型のコンストラクタ・デストラクタ・代入演算子のメタ情報を出力します。
template <typename T>
void output_constructor_and_destructor_and_assignop_metas()
{
auto fmtflags = wcout.flags();
wcout.setf(wcout.boolalpha);
wcout << typeid(T).name() << endl;
wcout << "一般" << endl
<< " コンストラクタ: " << is_constructible_v<T>
<< ", default: " << is_default_constructible_v<T>
<< ", copy: " << is_copy_constructible_v<T>
<< ", move: " << is_move_constructible_v<T> << endl
<< " 代入演算子: " << is_assignable_v<T, T>
<< ", copy: " << is_copy_assignable_v<T>
<< ", move: " << is_move_assignable_v<T> << endl
<< " デストラクタ: " << is_destructible_v<T> << endl;
wcout << "トリビアル" << endl
<< " コンストラクタ: " << is_trivially_constructible_v<T>
<< ", default: " << is_trivially_default_constructible_v<T>
<< ", copy: " << is_trivially_copy_constructible_v<T>
<< ", move: " << is_trivially_move_constructible_v<T> << endl
<< " 代入演算子: " << is_trivially_assignable_v<T,T>
<< ", copy: " << is_trivially_copy_assignable_v<T>
<< ", move: " << is_trivially_move_assignable_v<T> << endl
<< " デストラクタ: " << is_trivially_destructible_v<T> << endl;
wcout << "nothrow" << endl
<< " コンストラクタ: " << is_nothrow_constructible_v<T>
<< ", default: " << is_nothrow_default_constructible_v<T>
<< ", copy: " << is_nothrow_copy_constructible_v<T>
<< ", move: " << is_nothrow_move_constructible_v<T> << endl
<< " 代入演算子: " << is_nothrow_assignable_v<T,T>
<< ", copy: " << is_nothrow_copy_assignable_v<T>
<< ", move: " << is_nothrow_move_assignable_v<T> << endl
<< " デストラクタ: " << is_nothrow_destructible_v<T> << endl;
wcout << "仮想デストラクタ: "
<< has_virtual_destructor_v<T>
<< endl;
wcout << endl;
wcout.flags(fmtflags);
}
class TestClass
{
};
class TestClass2
{
public:
TestClass2(const TestClass2& c) = delete;
};
class TestClass3
{
public:
TestClass3() = default;
TestClass3(const TestClass3& c) = delete;
TestClass3(TestClass3&& c) = default;
};
int main()
{
output_constructor_and_destructor_and_assignop_metas<vector<int>>();
output_constructor_and_destructor_and_assignop_metas<int>();
output_constructor_and_destructor_and_assignop_metas<TestClass>();
output_constructor_and_destructor_and_assignop_metas<TestClass2>();
output_constructor_and_destructor_and_assignop_metas<TestClass3>();
return 0;
}
std::vectorの出力
出力
class std::vector<int,class std::allocator<int> >
一般
コンストラクタ: true, default: true, copy: true, move: true
代入演算子: true, copy: true, move: true
デストラクタ: true
トリビアル
コンストラクタ: false, default: false, copy: false, move: false
代入演算子: false, copy: false, move: false
デストラクタ: false
nothrow
コンストラクタ: true, default: true, copy: false, move: true
代入演算子: true, copy: false, move: true
デストラクタ: true
仮想デストラクタ: false
intの出力
出力
int
一般
コンストラクタ: true, default: true, copy: true, move: true
代入演算子: false, copy: true, move: true
デストラクタ: true
トリビアル
コンストラクタ: true, default: true, copy: true, move: true
代入演算子: false, copy: true, move: true
デストラクタ: true
nothrow
コンストラクタ: true, default: true, copy: true, move: true
代入演算子: false, copy: true, move: true
デストラクタ: true
仮想デストラクタ: false
空のクラスの出力
仮想デストラクタ以外は一式自動定義されています。
出力
class TestClass
一般
コンストラクタ: true, default: true, copy: true, move: true
代入演算子: true, copy: true, move: true
デストラクタ: true
トリビアル
コンストラクタ: true, default: true, copy: true, move: true
代入演算子: true, copy: true, move: true
デストラクタ: true
nothrow
コンストラクタ: true, default: true, copy: true, move: true
代入演算子: true, copy: true, move: true
デストラクタ: true
仮想デストラクタ: false
const参照コピーコンストラクタを削除したクラスの出力
コンストラクタが消えました。
出力
class TestClass2
一般
コンストラクタ: false, default: false, copy: false, move: false
代入演算子: true, copy: true, move: true
デストラクタ: true
トリビアル
コンストラクタ: false, default: false, copy: false, move: false
代入演算子: true, copy: true, move: true
デストラクタ: true
nothrow
コンストラクタ: false, default: false, copy: false, move: false
代入演算子: true, copy: true, move: true
デストラクタ: true
仮想デストラクタ: false
const参照コピーコンストラクタを削除、デフォルトコンストラクタとムーブコンストラクタをdefault指定したクラスの出力
デフォルトコンストラクタとムーブコンストラクタが存在します。コピーコンストラクタは存在しません。
出力
class TestClass3
一般
コンストラクタ: true, default: true, copy: false, move: true
代入演算子: false, copy: false, move: false
デストラクタ: true
トリビアル
コンストラクタ: true, default: true, copy: false, move: true
代入演算子: false, copy: false, move: false
デストラクタ: true
nothrow
コンストラクタ: true, default: true, copy: false, move: true
代入演算子: false, copy: false, move: false
デストラクタ: true
仮想デストラクタ: false