使用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
函数的调用会产生直接使用的值260
和264
在switch
上下文中;我应该承认我期待编译器抱怨“字符串不是常量表达式”。所以我转到下一步并尝试在算法中添加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
整个函数在编译时是可评估的。
为什么会这样?
答案 0 :(得分:6)
出现这种情况的原因与您无法做到的原因相同:
constexpr auto func(const int foo)
{
return std::array<int, foo>{};
}
foo
可能或者可能不是是一个常量表达式,具体取决于您调用func
的方式。但是你放入模板参数的内容必须是一个常量表达式。因此,此代码无法编译。
value
功能也是如此。你放入if constexpr
的内容必须是一个常量表达式,就像使用模板参数一样。所以你不能在那里放一些可能是也可能不是常量表达式的东西,比如constexpr
函数的参数。