首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非本地C++11 lambdas是否生活在匿名名称空间中?

非本地C++11 lambdas是否生活在匿名名称空间中?
EN

Stack Overflow用户
提问于 2012-07-18 04:23:09
回答 4查看 2K关注 0票数 7

最近构建的GCC 4.8在头文件中给出了以下代码:

代码语言:javascript
复制
auto L = [](){};

struct S
{
    decltype(L) m;
};

以下警告:

代码语言:javascript
复制
test.hpp:3:8: warning: 'S' has a field 'S::m' whose type uses the anonymous namespace [enabled by default]
 struct S
        ^

为什么编译器考虑使用匿名命名空间的lambda类型?我使lambda成为全局的,我在任何地方都没有使用匿名名称空间。

UPDATE:即使我将lambda放置在显式命名空间中,编译也会发出相同的警告,如下所示:

代码语言:javascript
复制
namespace N
{
    auto L = [](){};
}

struct S
{
    decltype(N::L) m;
};

更新2:实际上,类作用域lambda似乎也有相同的问题:

代码语言:javascript
复制
class N
{
    static constexpr auto L = [](){};
};

struct S
{
    decltype(N::L) m;
};
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-07-18 22:22:28

GCC的警告可能有点令人困惑,但它的意图肯定是正确的。lambda的类型是未命名的,它在整个程序中是唯一的。另一方面,如果您的类没有放在一个未命名的命名空间中(根据您的描述,我认为没有),那么您的类在包含它的每个翻译单元中都是相同的类型。因为同一个类应该有相同的成员,而不是不同翻译单元中的不同成员,这是一种违反(并导致未定义的行为)。

至少同样糟糕的是,Lextern,因此一旦将标题包含到多个翻译单元中,就会得到“L的多个定义”链接器错误。

票数 1
EN

Stack Overflow用户

发布于 2012-07-18 04:37:49

第5.1.2/3号编:

lambda-表达式的类型(它也是闭包对象的类型)是一个唯一的、未命名的非联合类类型(称为闭包类型),其属性如下所述。这个类类型不是一个聚合(8.5.1)。闭包类型在包含相应lambda表达式的最小块作用域、类作用域或命名空间范围中声明。

因此,除非在匿名命名空间中用代码定义lambda表达式,否则不应该将lambda的类型包含在匿名命名空间中。

票数 7
EN

Stack Overflow用户

发布于 2012-07-18 04:41:20

除非我遗漏了什么,否则它们都不应该出现在一个匿名的名称空间中,尽管GCC和MSVC似乎都把它们放在了那里。

§5.1.2 [expr.prim.lambda] p3

..。闭包类型在包含相应lambda表达式的最小块作用域、类作用域或命名空间范围中声明。..。

至少Clang似乎是正确的,闭包类型驻留在它应该在的位置。

(您可以通过简单地在某种类型的警告/错误生成代码中包含lambda来测试lambda类型驻留在哪个名称空间中。编译器应该将其类型与警告/错误一起显示出来。)

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

https://stackoverflow.com/questions/11534265

复制
相关文章

相似问题

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