强枚举typedef::虫还是c ++ 11标准不确定性?

时间:2018-10-24 14:11:02

标签: c++ c++11 enums language-lawyer

对于此类代码:

typedef enum FooEnum : int FooEnum;
enum FooEnum : int { A = 1, B };

clang(linux / 7.0.0)没有报告错误[-c -std=c++11 -pedantic], 但是gcc(linux / 8.2.1)无法编译它:

g++ -c -std=c++11 -pedantic test2.cpp
test2.cpp:1:28: error: expected ';' or '{' before 'FooEnum'
 typedef enum FooEnum : int FooEnum;
                            ^~~~~~~
test2.cpp:1:28: error: expected class-key before 'FooEnum'
test2.cpp:2:16: error: using typedef-name 'FooEnum' after 'enum'
 enum FooEnum : int { A = 1, B };
                ^~~
test2.cpp:1:28: note: 'FooEnum' has a previous declaration here
 typedef enum FooEnum : int FooEnum;

实际上我不知道为什么在C ++中将typedef用于枚举, 但问题是这是clang中的错误,因为它接受无效的代码, 还是这是c ++ 11标准中的错误,允许不同的实现?

更新:如前所述,第一个typedef用于objc ++兼容性, 在c ++代码编译和objc ++期间使用相同的标头。

2 个答案:

答案 0 :(得分:8)

这是一个叮叮当当的错误,您不能在typedef后面加上opaque-enum-declaration

[dcl.typedef]/1

  

defining-type-specifier ,[...]

之外,不得将typedef说明符与decl-specifier-seq与任何其他种类的说明符组合使用

[dcl.type]/1

  

定义类型说明符:

     
      
  • 类型说明符

  •   
  • 类说明符

  •   
  • 枚举说明符

  •   

[dcl.enum]/1

  

枚举说明符:

     
      
  • 枚举头{enumerator-listopt}

  •   
  • 枚举头{枚举器列表,}

  •   

因此下面的代码是合法的c ++:

typedef enum FooEnum : int { A = 1, B } FooEnum;

但这不是合法的c ++:

typedef enum FooEnum : int FooEnum;

因为enum FooEnum:int不是定义类型说明符

答案 1 :(得分:1)

typedef enum FooEnum : int FooEnum;

以上行无效。我认为您正在尝试转发声明。请参考下面的示例。

enum class FooEnum;

int fooStar(FooEnum&);

enum class FooEnum : int {
    A =1,
    B
};

int foo(FooEnum fooEnum) {
  return static_cast<int>(fooEnum);
}

int fooStar(FooEnum& fooEnum) {
  return static_cast<int>(fooEnum);
}