Search code examples
c++enum-classunderlyingtype

What is the purpose of `enum class` with a specified underlying type, but no enumerators?


The std::align_val_t type is defined as:

namespace std
{
    enum class align_val_t : size_t
    {
    };
}

What is the purpose of such an empty enumeration?

What's the difference with a typedef?


Solution

  • It is used as a strongly typed integer, which disables implicit type conversions.

    enum class strong_typed : size_t {};
    
    typedef size_t defed;
    
    int strong(strong_typed f);
    int weak(defed f);
    
    int main()
    {
        weak(defed{5}); // works
        weak(5); // works
    
        strong(strong_typed{5}); // works
        strong(5);               // error cannot convert int to strong_typed
        strong(size_t{5});       // error cannot convert size_t to strong_typed
    }
    

    godbolt demo

    you can get back the underlying type with std::to_underlying inside the function.

    Strongly typed integers are useful when you have a function accepting many arguments of the same type and you want to disambiguate them to avoid swapping arguments by mistake, or invoking the wrong overload.


    As for why it is used in std::align_val_t, according to Ted Lyngmo in the comments, it is likely to disambiguate operator new in the variadic case.

    // called by new (size_t{5}) T{};
    void* operator new  ( std::size_t count, size_t arg );
    
    // called by new T{}; on a T with large alignment
    void* operator new  ( std::size_t count, std::align_val_t al );