【发布时间】:2017-06-06 09:35:35
【问题描述】:
考虑这个例子,它将一个变量声明为 constexpr,通过在 lambda 中复制来捕获它,并声明另一个 constexpr 变量,该变量是 constexpr 函数从原始变量中解包非类型模板参数的结果。
#include <utility>
template<int I>
constexpr auto unwrap(std::integral_constant<int, I>) {
return I;
}
int main() {
constexpr auto i = std::integral_constant<int, 42>{};
constexpr auto l = [i]() {
constexpr int x = unwrap(i);
};
}
Clang(主干)接受此代码。 (wandbox)
GCC(主干)失败并显示以下错误消息 (wandbox):
lambda_capture.cpp:11:31: error: the value of ‘i’ is not usable in a constant expression
constexpr int x = unwrap(i);
^
lambda_capture.cpp:10:28: note: ‘i’ was not declared ‘constexpr’
constexpr auto l = [i]() {
哪个编译器是正确的?在我看来,这是一个 GCC 错误,其中 lambda 捕获的 constexpr-ness 没有正确传播到 lambda 上下文。
【问题讨论】:
-
考虑到 C++17 不是一个东西,但我不会说它们中的任何一个是对还是错。
-
同意@freakish,编译器可能会合理地犹豫要实现任何尚未具体设置的东西。
-
C++17 标准草案在 final stages of standardization 中,GCC 和 Clang 都声称是 language-feature complete。虽然还为时尚早,但我认为询问编译器如何实现新标准的问题是合理的,并且有助于编译器开发人员讨论事情最终应该如何工作。
-
我知道it 与 c++17 无关,但可能会有所帮助