c++ - GCC 和 Clang 不同意 lambda 的 constexpr-ness?
问题描述
为什么 Clang 无法编译以下代码,并显示表达式不是 constexpr 的消息,而 GCC 为什么没有?哪个编译器是正确的? https://godbolt.org/z/nUhszh (显然,这只是一个示例。事实上,我确实需要能够在 constexpr 上下文中调用 constexpr 函数对象。)
#include <type_traits>
template <typename Predicate>
constexpr int f(Predicate&& pred) {
if constexpr (pred(true)) {
return 1;
}
else {
return 0;
}
}
int main() {
f([](auto m) {
return std::is_same_v<decltype(m), bool>;
});
}
clang 8.0.0 的输出-std=c++17 -stdlib=libc++ -O1 -march=skylake
:
<source>:5:19: error: constexpr if condition is not a constant expression
if constexpr (pred(true)) {
^
<source>:14:5: note: in instantiation of function template specialization 'f<(lambda at <source>:14:7)>' requested here
f([](auto m) {
^
1 error generated.
Compiler returned: 1
解决方案
By using the predicate in an if constexpr
you expect it to be unconditionally a constant expression. But a constexpr
function can always be called in a non-constexpr context with arguments that are not constant expressions. So a function parameter may never be assumed to be a constant expression.
GCC is therefore wrong to accept your code unmodified.
It just so happens that your specific example doesn't require an if constexpr
to work in a constexpr context. A modified function:
template <typename Predicate>
constexpr int f(Predicate&& pred) {
if (pred(true)) {
return 1;
}
else {
return 0;
}
}
Is invocable by both compilers when a constant expression is required:
int main() {
constexpr int i = f([](auto m) constexpr {
return std::is_same_v<decltype(m), bool>;
});
return i;
}
推荐阅读
- java - 尝试在同一页面中显示输入的值
- python - 为什么我的 API 密钥在 Python 中的 base64 编码与外部软件对同一密钥的编码不同?
- python - 如何用 0 替换空字符串,但如果不为空则不理会
- github - 设置 Travis-CI 以仅构建已批准的拉取请求
- node.js - 在猫鼬中,如果值为 null,则不应将其添加到 MongoDB
- aem - AEM Query Builder 多个属性值
- heroku - Heroku 缺少必需的标志:-a,
- vba - 根据输入列值选择列表框的行
- c# - 用于批处理的 Azure 服务总线队列最大更新消息锁
- django - 如何在管理面板中限制样本