【问题标题】:Scoped enumerations: error: cannot convert ‘int’ to ‘Handle’ in initialization范围枚举:错误:无法在初始化中将“int”转换为“Handle”
【发布时间】:2016-09-21 16:27:52
【问题描述】:

我正在阅读来自hereScoped enumerations 页面:

所以我决定试一试:

$ 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的例子不是100%正确,还是GCC对C++11的支持还不完善?

【问题讨论】:

  • 你尝试在c++11中使用一个c++17的特性,不工作是完全正常的

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


【解决方案1】:

enum class(或enum struct)创建一个strong类型。它不能使用底层整数类型天真地初始化,它需要显式转换,至少在 C++11 和 C++14 中。

您展示的参考屏幕截图来自即将发布的 C++17 标准,它稍微放宽了要求,并允许进行这种类型的初始化。

【讨论】:

  • 这意味着cppreference 上的错字到目前为止未被注意到...对吗?
  • @malat 看看 cppreference 中的示例代码:它被标注为“since c++17”,所以不符合 c++11 也就不足为奇了
  • 我刚刚用 g++ 6.1.1 测试过它也失败了(-std=c++17 应该默认启用)并且明确添加了 -std=c++17 它是也不工作。
  • @KIIV 我没有使用 GCC 进行测试,但可以使用最近检查的 Clang(使用 clang++ -std=c++1z)。
  • @KIIV 是什么让您认为 GCC6 中默认启用了 C++17?发行说明说 gnu++14 是默认值。 C++17 不能成为默认值,因为还没有这样的东西。 (甚至还没有定义进入 c++17 的功能集)
【解决方案2】:

有问题的措辞来自P0138R2:枚举类值的构造规则。如您所见,这篇论文的日期是 2016 年 3 月——对于 C++11 来说已经晚了好几年!

按照建议,该措辞已包含在 [dcl.init.list] 中的最新工作草案 N4582 中:

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

clang 3.9 显然已经实现了这个例子,但我不会对编译器还不支持这些新特性感到惊讶。给它一段时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多