I'm attempting to limit the use of this function to enum classes that have unsigned underlying types (and have AddSubtract
as an enumeration) but I cannot for the life of me figure out the correct syntax.
template <class E>
concept EnumAddSubtract =
std::is_enum_v<E> &&
std::is_unsigned<std::underlying_type<E>::type> && //ERROR HERE
requires() { {E::AddSubtract}; };
template <EnumAddSubtract E>
constexpr E operator+(E const & lhs, int const & rhs) {
return static_cast<E>(static_cast<std::underlying_type<E>::type>(lhs) +
static_cast<std::underlying_type<E>::type>(rhs));
}
I'm able to call is_unsigned
on underlying_type<>::type
in other contexts, such as:
enum class C : unsigned {};
std::cout << std::is_unsigned<std::underlying_type<C>::type>::value << '\n';
I needed to take the value of is_unsigned. Using yeputons's suggestion to use helper function variants that end in _v and _t, here is code that compiles:
#include <iostream>
#include <type_traits>
template <class E>
concept EnumAddSubtract = std::is_enum_v<E> && std::is_unsigned_v<std::underlying_type_t<E>> && requires() { {E::AddSubtract}; };
template <EnumAddSubtract E>
constexpr E operator+(E const & lhs, int const & rhs) {
return static_cast<E>(static_cast<std::underlying_type<E>::type>(lhs) + static_cast<std::underlying_type<E>::type>(rhs));
}
enum class C : unsigned {};
typedef std::underlying_type<C>::type tester;
int main()
{
std::cout << std::is_unsigned<std::underlying_type<C>::type>::value << '\n';
std::cout << std::is_unsigned<tester>::value << '\n';
}