0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++ STL 型のコンストラクタ・デストラクタ・代入演算子情報を取得する

Last updated at Posted at 2020-06-08

目的

メタクラスを使って型のコンストラクタ・デストラクタ・代入演算子情報を取得するサンプルコードです。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
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?