Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::conditional_t for class type vs non-class type

How to fix this:

template<class T>
struct ResultType
{
    using type = std::conditional_t<std::is_class_v<T>, typename T::result_type, void>;
};

It cannot be it is supposed to return void, if T is not class type, but instead:

error: ‘int’ is not a class, struct, or union type 24 | using type = std::conditional_tstd::is_class_v<T, typename T::result_type, void>;

So I need to not try to invoke the false expression, but how?

like image 811
user877329 Avatar asked Mar 23 '26 20:03

user877329


1 Answers

In the following:

using type = std::conditional_t<std::is_class_v<T>, typename T::result_type, void>;

The part typename T::result_type will fail when T = int, because typename int::result_type is ill-formed.

You can fix this by using a template specialization instead of std::conditional which does the exact same thing but avoids doing T::result_type when T is not a class type:

#include <type_traits>

template <typename T, typename = void>
struct ResultType;

template <typename T>
struct ResultType<T, std::enable_if_t<!std::is_class_v<T>>> {
    using type = void;
};

template<typename T>
struct ResultType<T, std::enable_if_t<std::is_class_v<T>>> {
    using type = typename T::result_type;
};

// ...

struct X {
    using result_type = int;
};

int main() {
    static_assert(std::is_same_v<typename ResultType<X>::type, typename X::result_type>, "FAIL!");
    static_assert(std::is_same_v<typename ResultType<int>::type, void>, "FAIL!");
}
like image 161
Ruks Avatar answered Mar 26 '26 09:03

Ruks