Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Final enum classes in C++11

I am just curious whether an enum class can be final or not ... since the compilers are giving me contradictory results.

Consider the code:

#include <iostream>

enum class some_enums final : char
{
    a = 'a', 
    b = 'b',
    c = 'c'
};

int main()
{
    some_enums aa = some_enums::a;
    std::cout << "aa=" << static_cast<char>(aa) << std::endl;
}

Compiling this with Visual Studio 2015 compiler (http://rextester.com/l/cpp_online_compiler_visual) works... however compiling it with clang (http://rextester.com/l/cpp_online_compiler_clang) gives me an error:

source_file.cpp:3:30: error: expected ';' after top level declarator
        enum class some_enums final : char

I have seen no traces of final enum classes anywhere in the standard so I give credit to clang ... however why does Visual Studio accept it in this case although it is not mentioned in MSDN (https://msdn.microsoft.com/en-us/library/2dzy4k6e.aspx) ?

like image 268
Ferenc Deak Avatar asked Aug 30 '16 09:08

Ferenc Deak


1 Answers

The final specifier is used to signify that a class cannot be inherit from. Since an enum class cannot be inherited, the final specifier used in your case is useless.

"Stollen" from here and also mention in §7.2/p1 Enumeration declarations [dcl.enum] , a class enum declaration is of the form:

enum-key attr(optional) nested-name-specifier(optional) identifier enum-base(optional) ;
  • enum-key - one of enum, enum class (since C++11), or enum struct (since C++11)
  • attr (C++11) - optional sequence of any number of attributes
  • identifier - the name of the enumeration that's being declared. If present, and if this declaration is a re-declaration, it may be preceded by nested-name-specifier (since C++11): sequence of names and scope-resolution operators ::, ending with scope-resolution operator. The name can be omitted only in unscoped enumeration declarations.
  • enum-base (C++11) - colon (:), followed by a type-specifier-seq that names an integral type (if it is cv-qualified, qualifications are ignored).
  • enumerator-list - comma-separated list of enumerator definitions, each of which is either simply an identifier, which becomes the name of the enumerator, or an identifier with an initializer: identifier = constexpr. In either case, the identifier can be directly followed by an optional attribute specifier sequence. (since C++17).

Consequently, defining an enum class with final specifier as:

enum class some_enums final : char {
...
};

is not a standard form.

like image 117
101010 Avatar answered Sep 18 '22 10:09

101010