1
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 3 years have passed since last update.

【C++】型Tが暗黙に構築可能かどうか判定する、is_implicitly_constructibleクラスを作りました

Posted at

はじめに

型Tが引数Args...から暗黙に(implicitに)構築可能かどうか判定する、is_implicitly_constructibleクラスを作りました。

動機

自作のクラスのコンストラクタが、想定通りexplicitになっている(またはなっていない)のを確認したいことがあったので作りました。

実装

クラス宣言は以下のようになります。

// 型Tが引数Args...から暗黙に構築可能かどうか調べる
template <typename T, typename... Args>
struct is_implicitly_constructible;

これを実装するには、

template <typename T>
void func(T);

があったとき、func<T>({Args...});の形で呼び出し可能であれば、
型TはArgs...から暗黙に構築可能と言えますので、それを利用します。

// 実装のためのヘルパークラス
template <typename T, typename... Args>
struct is_implicitly_constructible_impl
{
private:
	template <typename T1>
	static void test_helper(T1);

	template <typename T1, typename... Args1>
	static auto test(int)
		-> decltype(test_helper<T1>({std::declval<Args1>()...}), std::true_type());

	template <typename T1, typename... Args1>
	static auto test(...) -> std::false_type;

public:
	using type = decltype(test<T, Args...>(0));
};

// is_implicitly_constructible定義
template <typename T, typename... Args>
struct is_implicitly_constructible
	: public is_implicitly_constructible_impl<T, Args...>::type
{};

実際にはもう少し考慮しなければいけないことがあるのですが、ここではわかりやすくするため簡略化しています。
完全なソースコードはGitHubに上げてあります。
https://github.com/shibainuudon/HamonEngine/blob/develop/libs/type_traits/include/hamon/type_traits/is_implicitly_constructible.hpp

使い方

struct S1
{
	S1(int);
};

struct S2
{
	explicit S2(int);
};

static_assert(is_implicitly_constructible<S1, int>::value == true);
static_assert(is_implicitly_constructible<S2, int>::value == false);

用途

型Sをラッピングするような型Tを作るときに、引数からSが暗黙に構築可能であるかどうかによって、Tのコンストラクタにexplicitをつけるかどうか切り替えるときなどに使えるのではないでしょうか。
関連:https://cpprefjp.github.io/lang/cpp20/explicit_bool.html

他の選択肢

Stack Overflowの方法で暗黙に構築可能か判定することもできると思います。
https://stackoverflow.com/questions/42786565/how-to-check-if-type-is-explicitly-implicitly-constructible
しかし、この方法は任意の引数に対応していません。

is_explicitly_constructibleを定義するかどうか

is_constructible && !is_implicitly_constructibleis_explicitly_constructibleと定義すると便利かもしれません。
しかし、implicitに構築可能である場合はexplicitにも構築可能なはずなので、名前とあっていないような気がします。1
explicitにのみ構築可能ということを表現する短い名前があるといいのですが・・・。

まとめ

is_implicitly_constructible、標準ライブラリにほしくないですか?

  1. 正しくするにはis_not_implicitly_constructible_but_explicitly_constructibleとか???

1
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
1
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?