Constexpr递归函数是否使用If ConstexPR
constexpr recursive function using if constexpr or not
使用GCC(HEAD 7.0.0 201612)我惊讶地发现这起作用:
constexpr long value(const char *definition)
{
if (definition && *definition)
{
return *definition + value(definition + 1);
}
return *definition;
}
int main()
{
long l{};
std::cin >> l;
switch (l)
{
case value("AAAA"): f1(); break;
case value("BBBB"): f2(); break;
default: error(); break;
}
return 0;
}
字面字符串"AAAA"
和"BBBB"
被视为编译时值,对value
函数的调用会产生直接在switch
上下文中使用的260
和264
的值;我应该承认,我期望编译器抱怨" 字符串不是恒定表达式"。因此,我搬到了下一步,并尝试将if constexpr
添加到算法:
constexpr long value(const char *definition)
{
if constexpr (definition && *definition)
{
return *definition + value(definition + 1);
}
return *definition;
}
但是,通过添加if constexpr
,代码不再编译:
In function 'constexpr long int value(const char*)': error: 'definition' is not a constant expression if constexpr (definition && *definition) ^
因此,definition
指针本身在if constexpr
上下文中无法在编译时间进行评估,但是使用传统的if
,可以在编译时间评估整个函数。
为什么会发生?
发生的原因是不能这样做的原因相同:
constexpr auto func(const int foo)
{
return std::array<int, foo>{};
}
foo
May 或可能不是是恒定表达式,具体取决于您调用func
的方式。但是,您将其放入模板参数必须是一个恒定的表达式。因此,此代码无法编译。
您的value
功能也是如此。您将其放入if constexpr
必须是一个恒定的表达式,就像模板参数一样。因此,您不能将某些内容放在那里可能会或可能不是恒定表达式的东西,例如constexpr
函数的参数。
相关文章:
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 三元运算符和 if constexpr
- C++20. is_constant_evaluated() vs if constexpr
- LLVM覆盖被if-constexpr混淆了
- 在if constexpr中使用带参数包的概念时,升级到gcc 9后出现编译错误
- 是否可以使用"if constexpr"来声明具有不同类型和init-expr的变量
- 对'if constexpr'的错误理解
- 从语言设计层面来看,当编译时无法推断条件时,为什么"if constexpr"不衰减到"trival if"
- 如何让编译器忽略这个计算结果为 false 的 if-constexpr?
- 无法编译包含"if constexpr"的函数模板实例化
- 从“if constexpr”分支扩展对象生存期/范围
- MSVC 和 clang for if constexpr 分支的不同行为
- 禁用具有"if constexpr"和 SFINAE 的分支
- 'if constexpr branch'不会在模板函数内的 lambda 中被丢弃
- 斐波那契和'if constexpr'
- 从编译器优化和代码性能的角度来看,"if constexpr"与"if"
- if constexpr的False分支未在模板化lambda中丢弃
- 在“if constexpr”块中声明的变量的范围
- 编译器之间在丢弃的 if constexpr(false) 语句中实例化模板的行为不一致