【发布时间】:2017-04-29 17:38:51
【问题描述】:
我一直试图了解何时以及何时不具有捕获默认 odr 的 lambda 使用具有在其周围范围内定义的自动存储持续时间的变量(由 this answer 提示)。在探索这个问题时,我遇到了一点好奇。 GCC 和 Clang 似乎对以下代码中 id-expression n 的值类别存在分歧:
template <typename T> void assert_is_lvalue(const T&) {}
template <typename T> void assert_is_lvalue(const T&&) = delete;
int main() {
const int n = 0;
[=] { assert_is_lvalue(n); };
}
Clang 成功编译代码,而 GCC 没有 (error: use of deleted function)。哪一个是正确的?或者这是未指定或实现定义的东西?
绑定对对象的引用应该是 odr-use 它,这通过删除 lambda 的默认捕获并观察到两个编译器抱怨 n 不能在没有捕获默认的情况下被隐式捕获来确认。
将 lambda 标记为 mutable 对编译器的输出没有明显影响。
【问题讨论】:
-
GCC 确实 not complain 关于
n如果我们删除默认捕获不会被捕获。似乎只是一个明显的错误。 -
@Columbo 很好发现,我错过了。不过,我不认为这是一个错误。我认为 gcc 将
n视为常量表达式,它可能是allowed to do。 -
是的,众所周知,GCC 会在 lambda 超早期错误地进行常量折叠。
-
它看起来像是编译器试图使 n constexpr 进行的过早优化,然后在您的示例中推导出右值并失败。绝对是 GCC 错误
-
适用于 gcc-8.1
标签: c++ lambda language-lawyer c++17 value-categories