首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >lambda内部的引用捕获对象的类型

lambda内部的引用捕获对象的类型
EN

Stack Overflow用户
提问于 2016-10-19 20:12:45
回答 1查看 453关注 0票数 17

以下代码适用于gcc

代码语言:javascript
复制
#include <map>

int main() {
    std::map<int, double> dict;
    const auto lambda = [&]()
    {
        decltype(dict)::value_type bar;
    };
}

但是对于msvc,我必须另外使用std::remove_reference

代码语言:javascript
复制
#include <map>
#include <type_traits>

int main() {
    std::map<int, double> dict;
    const auto lambda = [&]()
    {
        std::remove_reference_t<decltype(dict)>::value_type bar;
    };
}

否则我会得到an error

代码语言:javascript
复制
error C2651: 'std::map<int,double,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> &': left of '::' must be a class, struct or union

根据标准,哪个编译器显示了正确的行为?

更新:

对于msvc来说,decltype(dict)确实是一个参考,如以下代码所示

代码语言:javascript
复制
#include <map>

int main()
{
    std::map<int, double> dict;
    const auto lambda = [&]()
    {
        decltype(dict) foo;
    };
}

错误:

代码语言:javascript
复制
error C2530: 'foo': references must be initialized

如果这确实是错误的行为,当使用msvc编译代码时,可能会导致nasty bugs, like dangling references

代码语言:javascript
复制
#include <map>

std::map<int, double> return_a_map()
{
    std::map<int, double> result;
    return result;
}

int main()
{
    std::map<int, double> dict;
    const auto lambda = [&]()
    {
        decltype(dict) foo = return_a_map();
        // foo is a dangling reference in msvc
    };
}
EN

回答 1

Stack Overflow用户

发布于 2016-10-19 20:51:53

关于decltype的非括号应用程序没有特殊规则(即,[expr.prim.lambda]/20不适用)。所以我们只需要回到通常的decltype定义,它要求如果操作数是一个id表达式,那么产生的类型就是实体的声明类型,而不是引用类型。因此,VC++是错误的。

注意:dict是否被捕获并不重要,因为¶17

作为由copy捕获的实体的odr使用(3.2)的复合语句内的每个id表达式都被转换为对闭包类型的相应的未命名数据成员的访问。注意:对于不是odr-的 id-expression ,它指的是原始实体类型,而不是闭包类型的成员。此外,这样的id表达式不会导致对实体的隐式捕获。-结束注释

decltype从不odr-使用它的任何操作数或子操作数。实际上,这个规则有时会出现很多问题,如core issue 958中所示

int f ( int &);void* f (const int&);int main() {int i;=-> decltype(f(i)) { return f(i);};}

在这里,decltype(f(i))使用来自封闭作用域的非const i。但是,由于lambda不是mutable,所以主体中的i实际上是const,因此结尾返回类型是不正确的。CWG得出的结论是,这种情况出现的频率太低,不值得解决。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40131096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档