为什么 if constexpr 不会使这个核心常量表达式错误消失?
Why doesn't an if constexpr make this core constant expression error disappear?
参考此问题。用于初始化constexpr
变量y
的核心常数表达式不正确。给定的太多。
但是,如果我尝试将if
变成if constexpr
:
template <typename T>
void foo() {
constexpr int x = -1;
if constexpr (x >= 0){
constexpr int y = 1 << x;
}
}
int main(){
foo<int>();
}
错误仍然存在。GCC 7.2仍在给予:
error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
,但我认为应该将语义检查放在废弃的分支上。
通过constexpr
lambda进行间接确实有帮助,但是:
template <typename T>
void foo(){
constexpr int x = -1;
constexpr auto p = []() constexpr { return x; };
if constexpr (x >= 0){
constexpr int y = 1<<p();
}
}
y
上的constexpr
说明符似乎改变了如何检查丢弃的分支。这是预期的行为吗?
@max66 很友好,可以检查其他实现。他报告说,GCC(7.2.0/head 8.0.0)和clang(5.0.0/head 6.0.0)可重现该错误。
标准对 if constexpr
的丢弃语句的说法不多。关于这些:
- 在封闭的模板中,丢弃的语句未实例化。
- 从废弃的语句中引用的名称不需要ODR定义。
这些都不适用于您的用法:编译器是正确的,如果初始化,则可以抱怨constexpr
。请注意,当您想利用 Intantiation 失败时,您需要使条件取决于模板参数:如果值不依赖于模板参数,则当失败时发生故障模板是定义的。例如,此代码仍然失败:
template <typename T>
void f() {
constexpr int x = -1;
if constexpr (x >= 0){
constexpr int y = 1<<x;
}
}
但是,如果您使x
取决于类型T
,即使使用f
实例化了int
:
template <typename T>
void f() {
constexpr T x = -1;
if constexpr (x >= 0){
constexpr int y = 1<<x;
}
}
int main() {
f<int>();
}
请注意,对于constexpr丢弃的语句,如果:
对于每一个可能的专业化,都不能对废弃的说明进行不良形式:
要解决问题,您可以根据模板参数进行声明,例如
template<typename T, int X> struct dependent_value { constexpr static int V = X; };
template <typename T>
void foo() {
constexpr int x = -1;
if constexpr (x >= 0){
constexpr int y = 1 << dependent_value<T, x>::V;
}
}
live
我不确定为什么您希望不检查分支。如果分支是"未检查"的唯一时间是它是模板的一部分而不是实例化,则根据[stmt.if] p2:
在封闭模板的实例化期间 实体(第17条),如果条件在实例化后不取决于价值,则废弃的取代 (如果有)未实例化。
您的代码似乎不在适用的情况下。
相关文章:
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 什么时候在C++中返回常量引用是个好主意
- 代理对象的常量正确性
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 通过多个头文件使用常量变量
- 如何找出GDB的SIGTRAP核心转储的根本原因
- C++映射分割错误(核心转储)
- 在cuda线程之间共享大量常量数据
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 尽管测试成功,CppUnit测试核心仍被丢弃.为什么
- 是默认情况下分配给char数组常量的值
- 私有类型的静态常量成员
- 类似枚举的计算常量
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 返回常量和核心转储的函数
- 为什么 if constexpr 不会使这个核心常量表达式错误消失?
- C++11标准中的核心常量表达式是什么
- `核心常量表达式与常量表达式