Clang抱怨ConstexPR函数在switch语句的情况下
clang complains about constexpr function in case for switch statement
struct X
{
enum class E
{
A,B
};
static constexpr X A()
{
return X{E::A};
}
static constexpr X B()
{
return X{E::B};
}
constexpr operator E() const
{
return a;
}
E a;
};
template <typename T>
struct Y
{
void f()
{
// without this line clang errs
// const auto & x = this->x;
switch(x)
{
case X::A():
case X::B():
default: return;
}
}
X x = X::A();
};
int main()
{
Y<int>{}.f();
}
如果代码段中没有标记的行,则 clang 会给出以下错误:
错误:大小写值不是常量表达式大小写
X::B((:
但是我尝试了 gcc,它编译得很好。有人知道 gcc 是宽容还是 clang 有一些错误?
参见 godbolt (clang 8.0.0(: https://godbolt.org/z/ETe5WQ但是(gcc 8.3(编译得很好(也在godbolt上(,并尝试了其他版本的gcc,也很好
更新:
打开了一个错误
Clang (8.0.0( 这里有一个错误。
如果您编写constexpr auto A = X::A();
并在 switch
语句中使用 case A:
,则会收到相同的编译错误(表示 A
不是常量表达式(。
但是,如果删除这些大小写,它会编译良好(这意味着A
是有效的constexpr
=>与前一个错误相矛盾(。
此外,switch(x)
失败而switch(this->x)
成功。由于x == this->x
在您的情况下,这绝对是一个错误。
正如chtz所提到的,clang(5/6(似乎工作得很好。这不是一个论点,而是一个明显的倒退。
更新:正如OP所提到的,他们提交了错误报告。
似乎 clang 无法确定 switch(x)
是枚举X::E
上的开关。
如果将显式强制转换添加到X::E
(static_cast
或 C 样式或其他样式(,则代码无需更改即可编译。
仅当您的类是template
时,才会发生这种情况。
使用switch(this->x)
也有效。
因为每当x
是类的成员时,x
也只是this->x
的另一个名字,即使在template
中,这也必须是一个叮当错误。
有关如何对非枚举/整型进行切换的规则很有趣,因为它们依赖于switch
表达式中任何枚举或整型类型的未指定强制转换运算符的存在,然后在case
表达式中调用相同的强制转换。
- 如何在没有打印语句的情况下报告用户输入错误
- 如何在不中断的情况下正确使用C++中的切换用例语句中的Fallthrough
- 如果 return 语句在带括号的循环中,错误可能会到达非 void 函数的末尾,但不会显示在没有括号的循环的情况下
- 如果在不需要的情况下运行语句
- Clang抱怨ConstexPR函数在switch语句的情况下
- 这段代码如何在没有任何循环语句或'goto'或递归的情况下循环?
- 在不使用单个 if 的情况下执行一些语句
- 在允许的情况下更改开关语句键
- 在情况下,如何循环回到开关语句的开头
- 'new'语句是否可以在不引发异常的情况下失败?
- 如何使用C++在没有多个if-else语句的情况下编写以下代码
- 如何在不使用if语句的情况下查找数组中的最大值和最小值
- 返回 std::string 的函数在没有 return 语句的情况下崩溃,这与返回 int 而不返回语句的函数不同
- 如何在<T>没有 if 语句的情况下返回可选?
- 在什么情况下,if语句可以抛出异常
- 我将如何在不使用 if 语句、字符数组、apstring 或 atoi 的情况下将带有两位数字的字符串转换为 int
- 在多个return语句的情况下,返回时带有“std::move”明智
- catch语句如何在没有反射的情况下识别异常类型
- Sqlite3/C++在不更改数据库大小的情况下执行DELETE语句
- 是否有可能在不使用指针的情况下将变量的作用域扩展到if语句之外?