gpt4 book ai didi

c++ - 通过显式转换函数初始化枚举类类型的静态 constexpr 类成员

转载 作者:可可西里 更新时间:2023-11-01 16:42:30 25 4
gpt4 key购买 nike

我在 g++ 4.8.1 和 clang++ 3.4 的行为之间存在差异。

我有一个 A 类,它是文字类型的,它有一个 explicit constexpr 转换函数来输入 enum class E.

Gcc 允许我在某些情况下使用转换函数从 A 类型的常量表达式初始化 constexpr 类型的 E 变量,但是不是当变量是静态类成员时(下面的 e2)

Clang 拒绝所有上下文中的初始化(e1e2e3)。

根据[over.match.conv]p1,在这里可以使用显式转换函数

enum class E { e };
struct A { explicit constexpr operator const E() const noexcept { return E::e; } };

constexpr E e1{A{}}; // Gcc: OK, Clang: Error
struct B { static constexpr E e2{A{}}; }; // Gcc: Error, Clang: Error
void f() { static constexpr E e3{A{}}; } // Gcc: OK, Clang: Error

当转换为另一个文字类类型而不是枚举类型时,我看到了类似的模式 - g++ 拒绝 s1 的初始化,clang 拒绝 s1 的初始化,s2s3。根据 [over.match.copy]p1,我认为这些也应该有效。

struct S { constexpr S(){} constexpr S(const S&){}};
struct A { explicit constexpr operator S() const noexcept { return S(); } };

constexpr S s1{A{}}; // Gcc: OK, Clang: Error
struct B { static constexpr S s2{A{}}; }; // Gcc: Error, Clang: Error
void f() { static constexpr S s3{A{}}; } // Gcc: OK, Clang: Error

哪个编译器是正确的?


编辑:需要注意的一些有趣的事情:

  1. clang-3.4 和 clang-svn 的结果不同,见下面的评论。
  2. 当使用 parens 代替大括号进行初始化时,e2/s2e1/e3 之间仍然存在差异/s1/s3,参见http://coliru.stacked-crooked.com/a/daca396a63425c6b . gcc 和 clang-svn 同意,但我不相信拒绝 e2 和 s2 是正确的。

最佳答案

奇怪的是,Clang 拒绝这些似乎是正确的。

原因是 C++11 标准中存在 {} 不适用于复制构造函数的错误。这就是 () 构造函数起作用,而 {} 构造函数不起作用的原因。

Bjarne Stroustrup 在 errata for his book 下说它在 C++14 中得到修复

关于c++ - 通过显式转换函数初始化枚举类类型的静态 constexpr 类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20972634/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com