I'm having a hard time understanding how to stop code from being evaluated with std::conditional_t
in the false branch.
#include <type_traits>
using namespace std;
namespace {
template <typename T>
using BaseDifferenceType = decltype (T{} - T{});
}
int main ()
{
using T = int;
static_assert(! is_enum_v<T>);
BaseDifferenceType<T> xxx {};
// PROBLEM IS HERE - though is_enum is false, we still evaluate underlying_type<T> and complain it fails
using aaa = conditional_t<is_enum_v<T>, underlying_type_t<T>, BaseDifferenceType<T>>;
return 0;
}
You can try this online at https://www.onlinegdb.com/uxlpSWVXr.
Compiling (with C++17) gives the error:
error: ‘int’ is not an enumeration type
typedef __underlying_type(_Tp) type;
^~~~ main.cpp: In function ‘int main()’: main.cpp:16:87: error: template argument 2 is invalid
using aaa = conditional_t<is_enum_v<T>, underlying_type_t<T>, BaseDifferenceType<T>>;
A possible alternative pass through a creation of a custom type traits as follows
and rewrite your
std::conditional
as followsObserve I've added a final
::type
: it's the "constructor" of the required type, completely avoiding the unwanted type.Off Topic Unrequested Suggestion: avoid
It's considered bad practice