忍者ブログ

VIEWブログ

tk-xleaderのブログ。C++などプログラミングの話題が中心です。

【C++2a】std::is_nothrow_convertibleのC++17での実装例

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

【C++2a】std::is_nothrow_convertibleのC++17での実装例

std::is_nothrow_convertibleは、C++2aで<type_traits>ヘッダに追加されるメタ関数で、型Fromから型Toに暗黙変換が可能であり、例外を投げないことが保証されているかどうかを調べるものです。

TからUに暗黙変換が可能というのは、
U func(){ return std::declval<T>();}
という関数が有効ということを意味しますが、SFINAEでは、戻り値の有効性はチェックできませんから、これを何とか引数に持ってきます。
その結果、C++17では、is_nothrow_convertibleはこのような実装になります。

namespace std{
	namespace _details{
		template<typename To>
		std::void_t<To()> convert_to(To) noexcept;
		
		template<typename From, typename To, typename = void>
		struct is_nothrow_convertible_imp : std::false_type{};

		template<typename From, typename To>
		struct is_nothrow_convertible_imp<From, To, typename std::enable_if<noexcept(std::_details::convert_to<To>(std::declval<From>()))>::type> : std::true_type{};
	}

	template<typename From, typename To>
	struct is_nothrow_convertible : std::conditional<
		std::is_void<From>::value,
		std::is_void<To>,
		_details::is_nothrow_convertible_imp<From, To>
	>::type{};
}
関数の引数と戻り値のどちらでも暗黙変換が起こりうる文脈ですが、
  • 関数の仮引数の型が、配列型・関数型となっている場合、decayが発生するが、戻り値型の場合はこれが起こらずエラーになる。
  • 関数の戻り値型がvoidの場合にvoid型を返す関数の呼び出しをreturn文の式に記述できるが、仮引数型がvoidの場合はこれができずエラーになる。
という点で違いますから、次のようにすることで、return文で判定したときと一致するようにさせます。
  • Fromがvoidの場合、Toがvoidかどうかを判定する。
  • convert_toヘルパ関数の戻り値をstd::void_t<To()>とすることで、Toが配列型・関数型の場合にconvert_toヘルパ関数が不正なシグネチャとなるように細工する。
detection idiomの変則系として、std::void_tではなくて、std::enable_ifを使うもできます。
PR

コメント

プロフィール

HN:
tk-xleader
Webサイト:
性別:
男性

カテゴリー

P R