c++stdc++20enum-class

Can't manage to call is_unsigned on the underlying_type of an enum class template parameter


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';

Solution

  • 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';
    }