如果 constexpr 给出错误,则在 false 中实例化模板函数
Instantiating template function in a false if constexpr gives error
考虑以下程序:
#include <iostream>
template<typename... Params_t>
constexpr int constexprValue(Params_t...) { return 5; }
int main()
{
const bool flag = true;
if constexpr(flag)
{
constexpr int value = constexprValue(1, 2, 3);
std::cout << value << "\n";
}
}
这可以编译并且工作正常。但是,如果flag
改为false
,则clang(Apple LLVM version 10.0.0 (clang-1000.10.44.4))给出编译错误:
error: constexpr variable 'value' must be initialized by a constant expression
undefined function 'constexprValue<int, int, int>' cannot be used in a constant expression
这是 clang 中的错误吗?
是的,这似乎是 Apple 版本的 clang 中的错误,我能够使用 clang 版本 5 及更高版本以及 gcc 版本 7.1 及更高版本编译代码。
Matt Godbold 有一个很棒的网站,可以使用大量不同的编译器编译代码片段。
Here 是 link 你在 godbolt 中的例子。
是的,这是一个已被此 commmit to clang: [Sema] Discarded statment should be an evaluatable context. 修复的错误,具有以下描述:
The constexpr evaluator was erroring out because these templates weren't
defined. Despite being used in a discarded statement, we still need to constexpr
evaluate them, which means that we need to instantiate them. Fixes PR37585.
Differential revision: https://reviews.llvm.org/D48322
并包括以下测试:
namespace PR37585 {
template <class T> struct S { static constexpr bool value = true; };
template <class T> constexpr bool f() { return true; }
template <class T> constexpr bool v = true;
void test() {
if constexpr (true) {}
else if constexpr (f<int>()) {}
else if constexpr (S<int>::value) {}
else if constexpr (v<int>) {}
}
}
如果我们尝试实时测试 with godbolt with an older clang version,我们会得到一个与您的示例所看到的非常相似的错误诊断:
error: constexpr if condition is not a constant expression
else if constexpr (f<int>()) {}
^~~~~~~~
note: undefined function 'f<int>' cannot be used in a constant expression
修复源自 bug report: constexpr if condition is not a constant expression and std::is_same。
考虑以下程序:
#include <iostream>
template<typename... Params_t>
constexpr int constexprValue(Params_t...) { return 5; }
int main()
{
const bool flag = true;
if constexpr(flag)
{
constexpr int value = constexprValue(1, 2, 3);
std::cout << value << "\n";
}
}
这可以编译并且工作正常。但是,如果flag
改为false
,则clang(Apple LLVM version 10.0.0 (clang-1000.10.44.4))给出编译错误:
error: constexpr variable 'value' must be initialized by a constant expression
undefined function 'constexprValue<int, int, int>' cannot be used in a constant expression
这是 clang 中的错误吗?
是的,这似乎是 Apple 版本的 clang 中的错误,我能够使用 clang 版本 5 及更高版本以及 gcc 版本 7.1 及更高版本编译代码。
Matt Godbold 有一个很棒的网站,可以使用大量不同的编译器编译代码片段。
Here 是 link 你在 godbolt 中的例子。
是的,这是一个已被此 commmit to clang: [Sema] Discarded statment should be an evaluatable context. 修复的错误,具有以下描述:
The constexpr evaluator was erroring out because these templates weren't defined. Despite being used in a discarded statement, we still need to constexpr evaluate them, which means that we need to instantiate them. Fixes PR37585.
Differential revision: https://reviews.llvm.org/D48322
并包括以下测试:
namespace PR37585 {
template <class T> struct S { static constexpr bool value = true; };
template <class T> constexpr bool f() { return true; }
template <class T> constexpr bool v = true;
void test() {
if constexpr (true) {}
else if constexpr (f<int>()) {}
else if constexpr (S<int>::value) {}
else if constexpr (v<int>) {}
}
}
如果我们尝试实时测试 with godbolt with an older clang version,我们会得到一个与您的示例所看到的非常相似的错误诊断:
error: constexpr if condition is not a constant expression
else if constexpr (f<int>()) {}
^~~~~~~~
note: undefined function 'f<int>' cannot be used in a constant expression
修复源自 bug report: constexpr if condition is not a constant expression and std::is_same。