ラムダ式の型かどうかを返すtemplateクラスを作ってみました!
キャプチャを行っていないラムダ式のみ対応しています。
用途は特に思い付きません。
1.関数型かどうか
関数ポインタ型かどうかを返すtype_traitsってあるんでしょうか?
void(*)()がstd::is_functionだとfalseになるので、別途templateクラスを用意しています。
IsFunction.h
template<class T>
struct IsFunction : std::false_type {};
template<class T>
requires(
std::is_function_v<T> ||
std::is_member_function_pointer_v<T>
)
struct IsFunction<T> : std::true_type {};
template<class _R, class... Args>
struct IsFunction<_R(*)(Args...)> : std::true_type {};
template<class _R, class... Args>
struct IsFunction<_R(*)(Args...)noexcept> : std::true_type {};
template<class T>
constexpr bool IsFunctionV = IsFunction<T>::value;
2.ラムダ式の型かどうか
+
単項演算子で、ラムダ式の型を関数ポインタ型へ変換できるようです。
関数型じゃない且つ関数ポインタ型へ変換可能かどうかを見ています。
IsLambda.h
template<class T>
struct IsLambda : std::false_type {};
template<class T>
requires(IsFunctionV<T>)
struct IsLambda<T> : std::false_type {};
template<class T>
requires(!IsFunctionV<T>&& std::is_object_v<decltype(+T())>)
struct IsLambda<T> : std::true_type {};
template<class T>
constexpr bool IsLambdaV = IsLambda<T>::value;
2.テスト
※MSVCとclangで動作確認しています。
Test.cpp
class TestClass{};
void Test()
{
static_assert(IsLambdaV<decltype([]() {}) >);
static_assert(IsLambdaV<decltype([](int, float) {}) >);
static_assert(!IsLambdaV<void() >);
static_assert(!IsLambdaV<void(*)() >) ;
static_assert(!IsLambdaV<void(TestClass::*)() >);
};
ググっても誰もやっていないのでラムダ式かどうかを判定するのは推奨されていないんですかね...?