作用域枚举:错误:无法将“int”转换为“Handle”进行初始化。

4

我正在阅读这里作用域枚举页面:

输入图像描述 所以我决定试一试:

$ cat e.cxx 
#include <cstdint>
enum class Handle : uint32_t { Invalid = 0 };
int main()
{
  Handle h { 42 }; // OK
  return 0;
}
$ g++ -std=c++11 e.cxx
e.cxx: In function ‘int main()’:
e.cxx:5:17: error: cannot convert ‘int’ to ‘Handle’ in initialization
   Handle h { 42 }; // OK

             ^

使用:
$ g++ --version
g++ (Debian 5.3.1-14) 5.3.1 20160409
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

如果我现在检查GCC中的C++11支持,似乎自GCC 4.8以来所有内容都得到了支持。
那么我是在看错哪一页?Score enumertions的示例不是完全正确的,或者GCC对C++11的支持仍然不完整?

1
你试图在c++11中使用c++17的特性,这是完全正常的,它不会起作用。 - Garf365
2个回答

5
enum class(或enum struct)创建了一个强类型。它不能使用底层整数类型进行简单初始化,至少在C++11和C++14中需要显式转换。
您展示的参考截图来自即将发布的C++17标准,该标准放宽了要求,并允许该类型的初始化。

这意味着cppreference上有一个拼写错误,但迄今为止还没有被注意到...对吗? - malat
2
@malat,请看cppreference中的示例代码:它被标注为“自C++17以来”,所以它不符合C++11并不令人意外。 - Garf365
我刚刚使用g++ 6.1.1进行了测试,但它也失败了(-std=c++17应该默认启用),即使明确添加了-std=c++17也不起作用。 - KIIV
@KIIV 我没有使用GCC进行测试,但是最近使用Clang的检出版本可以工作(使用clang++ -std=c++1z)。 - Some programmer dude
@KIIV你为什么认为GCC6默认启用C++17?发行说明指出“gnu++14”是默认设置。C++17不能是默认设置,因为它还不存在。 (即使进入c++17的功能集尚未定义) - Ilya Popov

1
这段文字来自P0138R2: 枚举类值的构造规则。可以看到,该文件的日期是2016年3月,比C++11晚了很多年!该措辞在最新的工作草案N4582中已经包含在[dcl.init.list]中建议如下:

否则,如果T是具有固定基础类型的枚举类型(7.2),[...]

clang 3.9似乎已经实现了这个例子,但我不会惊讶于这些新功能尚未被编译器支持。再等一段时间吧。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接