Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 静态成员初始值设定项的lambda作用域_C++_C++11_Lambda - Fatal编程技术网

C++ 静态成员初始值设定项的lambda作用域

C++ 静态成员初始值设定项的lambda作用域,c++,c++11,lambda,C++,C++11,Lambda,我的问题是关于静态成员初始值设定项的lambda范围。考虑下面的测试: #include <functional> #include <iostream> struct S { static const std::function<void(void)> s_func; }; const std::function<void(void)> S::s_func = []() { std::cout << "Hello

我的问题是关于静态成员初始值设定项的lambda范围。考虑下面的测试:

#include <functional>
#include <iostream>

struct S {
    static const std::function<void(void)> s_func;
};

const std::function<void(void)> S::s_func = []() {
    std::cout << "Hello from " << __PRETTY_FUNCTION__ << std::endl;
};

int main(void) {
    S::s_func();
    return 0;
}
可能较新的gcc更符合标准。但是,我想问一下,标准是否实际指定了这一方面,或者它可能依赖于实现

更新:正如@user5434961所建议的那样,所有类似于
\uuuuuuuuuuuuu函数
的宏都依赖于实现,因此最好在符合标准的测试中避免它们。下面是一个示例,如果编译器在
S
范围内定义了这样的lambda,并在其他情况下中断编译,则可以编译该示例:

#include <functional>
#include <iostream>

struct S {
    static const std::function<void(void)> s_func;
private:
    static const int s_field;
};

const std::function<void(void)> S::s_func = []() {
    std::cout << "Hello from S::s_func. S::s_field = " << S::s_field << std::endl;
};

const int S::s_field = 1;

int main(void) {
    S::s_func();
    return 0;
}
#包括
#包括
结构{
静态常量std::函数s_func;
私人:
静态常量int s_字段;
};
常量std::函数S::S_func=[](){

std::cout这个问题以前曾被提出过,但我找不到相关的错误报告。这里是一个MSVC错误报告的示例,该报告应该已经归档(2015年仍未修复:您可以在上进行测试)。但是对于GCC,它已经被修复在4.7到4.8之间。用于作为错误备份的相关标准是:

[C++11,9.4.2/2]定义a的初始值设定项表达式
静态
数据成员在其类的范围内

[C++11,5.1.2/2]对lambda表达式的求值会产生prvalue临时值(12.2)。该临时值称为闭包对象。lambda表达式不得出现在未求值的操作数中(第5条)

[C++11,5.1.2/3]lambda表达式的类型(也是 闭包对象的类型)是唯一的、未命名的非并集类类型 -调用闭包类型-其属性如下所述 类类型不是聚合(8.5.1)。已声明闭包类型 在最小的块作用域、类作用域或命名空间作用域中 包含相应的lambda表达式

之前


我想它应该在课堂范围内。引用自(我的重点):

lambda表达式构造一个未命名的prvalue临时对象 唯一的未命名非并集非聚合类型,称为闭包类型, 在最小的块中声明(用于ADL) 包含lambda的作用域、类作用域或命名空间作用域 表达式


S::S_func
的越界定义中,您进入
S
的范围,遇到时间
S:
。因此,lambda表达式包含在
S
的类范围中。由于closer类型是
S
的成员,因此可以访问
S
的私有成员。

我想您应该这样做在更新的示例中,将
S::S_字段
更改为仅
S_字段
?否则,我认为它总是编译任何作用域。因为
S::S_字段
是私有的,它不能从全局作用域访问,因此代码确实破坏了GCC-4.7索引上的编译是的,是的。我忽略了私有的东西。谢谢大家nd@user5434961获得同样有用的答案。我将他的答案标记为已接受,因为它比你的答案早了一点。@user3159253不客气:)user5434961的答案比我的答案更好,因为它引用了标准文档。
Hello from <lambda()>
#include <functional>
#include <iostream>

struct S {
    static const std::function<void(void)> s_func;
private:
    static const int s_field;
};

const std::function<void(void)> S::s_func = []() {
    std::cout << "Hello from S::s_func. S::s_field = " << S::s_field << std::endl;
};

const int S::s_field = 1;

int main(void) {
    S::s_func();
    return 0;
}