Pap*_*ter 4 c++ constexpr c++17
使用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;
}
Run Code Online (Sandbox Code Playgroud)
的文字串"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;
}
Run Code Online (Sandbox Code Playgroud)
但是通过添加if constexpr代码不再编译:
Run Code Online (Sandbox Code Playgroud)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>{};
}
Run Code Online (Sandbox Code Playgroud)
foo可能会也可能不会是一个恒定的表达,取决于你如何调用func.但是你放入模板参数的必须是一个常量表达式.因此,此代码无法编译.
你的value功能也一样.你输入的内容if constexpr 必须是一个常量表达式,就像模板参数一样.所以你不能在那里放一些可能是也可能不是常量表达式的东西,比如constexpr函数的参数.