【发布时间】:2016-01-09 12:26:09
【问题描述】:
我的问题是关于静态成员初始值设定项的 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 从 4.8 开始定义了 S 范围内的 lambda,所以程序输出如下:
Hello from S::<lambda()>
(gcc-4.8.2 对__FUNCTION__ & Co 宏有不同的定义,但是 lambda 仍然在 S 中定义)
同时 gcc-4.7 在全局范围内定义了 lambda,所以程序输出
Hello from <lambda()>
可能较新的 gcc 更符合标准。但是我想问一下标准是否真的指定了这个方面,或者它可以是依赖于实现的。
更新:正如@user5434961 所建议的,所有__FUNCTION__-alike 宏都依赖于实现,因此最好在符合标准的测试中避免使用它们。因此,如果编译器在 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;
}
【问题讨论】:
-
我猜你应该在更新的示例中将
S::s_field更改为s_field?否则,我认为它总是可以编译任何范围。 -
好吧,由于
S::s_field是私有的,因此无法从全局范围访问它,因此代码确实会破坏 GCC-4.7 上的编译 -
是的,是的。我忽略了私人的事情。