G++ 不允许在 lambda 中通过引用对 const 对象进行广义捕获?
g++ won't allow generalized capture of const object by reference in lambda?
这被g++(4.9.3和5.2.0)拒绝,但被clang 3.5.0接受:
int main() {
const int ci = 0;
auto lambda = [ &cap = ci ]() { };
}
g++给出error: binding ‘const int’ to reference of type ‘int&’ discards qualifiers
。看来c++不允许捕获非const引用,当然除了使用普通的c++ 11捕获[&ci]
。这似乎是一个非常奇怪的约束,也许是g++中的一个bug ?
您的代码有效。§5.1.2/11是
init-capture的行为就好像它声明并显式捕获了一个形式为
"auto
init-capture;
" 的变量,该变量的声明区域是lambda表达式的复合语句[…]
现在,很明显,声明
auto &cap = ci;
和捕获cap
是可以的。也就是说,
int main() {
const int ci = 0;
auto &cap = ci;
auto lambda = [&cap]() { };
}
使用GCC编译。除了cap
的声明性区域和生命周期之外,这个代码片段和您的代码片段没有区别,因此GCC是不正确的。
这个bug已经被报告为#66735,还有一个类似的例子:
int x = 0;
auto l = [&rx = static_cast<const int&>(x)] {};
这看起来类似于gcc的错误:[c++ 14] lambda init-capture const引用失败,显示:
这段代码编译失败:
int main() { int x = 0; auto l = [&rx = static_cast<const int&>(x)]() {}; }
错误信息是:
test.cpp:3:14:错误:绑定'const int'到类型'int&'的引用丢弃限定符
auto l = [&rx = static_cast<const int&>(x)]() {
但是根据[exp .prim]。/11rx应该被捕获为auto&rx = static_cast(x),即const int&
bug报告引用了[expr.prim]。Lambda]/11表示:
init-capture的行为就好像它声明并显式捕获了一个形式为"auto init-capture;"的变量。其声明区域是lambda表达式的复合语句,但[…]
- 被解释为低级别const的const对象的地址
- 使用共享指针的函数调用,其对象应为 const
- 如何从构造函数副本 T(const T&)调用对象 T?
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- Google Or-Tools Glop:如何创建指向 const 对象的指针数组?
- 无法使用类型 'const char *' 的左值初始化类型 'char *' 的成员子对象
- 我们可以有一个 setter 成员函数作为从 const 对象引用的 const 吗?
- "this"指向的对象是否与 const 对象相同?
- const auto & 和 auto & if reference 对象之间的区别是 const
- 将对象传递给函数而不将其包装到 std::ref 中,而参数被指定为 const 引用
- C++ - 确定 const char* 是指向字符串文本对象还是动态对象
- 为什么 const YAML::Node 对象的行为不像 yaml-cpp 中的类似值的对象?
- 从 const 对象访问非 const 方法
- 将非 const 对象用于 const 参数
- 如何键入用于const对象的自定义io操纵器
- 对临时对象的Const引用不会延长其生存期
- 正在通过const-ref未定义的行为捕获新构造的对象
- 具有成员变量的对象 Const 数组 = 先前索引成员变量的总和
- 为什么我构建的临时对象const不可变
- 强制用户声明对象const