[英]Static Auto Variable in Generic Lambda in C++14
class A {
public:
int a;
char b;
double c;
A ( int x, char y, double z ) : a(x), b(y), c(z){}
};
int main(){
auto lambda = []( auto x ) {
static auto y = x;
// y = x;
return y;
};
int a = lambda(1);
char b = lambda('a');
double c = lambda(1.5);
A d = lambda( A( 2, 'b', 2.5 ) );
return 0;
}
该代码在Clang 3.8.0和GCC 5.4.0中编译,并且工作正常。 但是,考虑到变量y
是static
:
y
的类型是什么? 每次调用lambda时y
的类型都会改变吗? static
变量y
是否在每个调用中都初始化了吗? 注释的// y = x
不需要更新变量y
的值。 如果我在每个调用中打印sizeof(y)
,则分别得到4、1、8和16。
您的lambda是泛型的 。 这意味着这是变相的模板。 根据模板专业化的一般规则处理该情况。
对于参数x
每种特定推导类型,您将获得函数的单独专业化。 因此,是的,对于每种特定的x
类型,您都会得到y
的单独副本。 但是底层机制并未以某种方式局部化在您的static
,而是“复制”函数的整个主体以生成该函数的独立的独立实现。
lambda的每个特化将具有y
的单独副本,该副本仅在首次调用该特化时才初始化一次。
这种情况实际上相当于更明确
template <typename T> void foo(T x)
{
static T y = x;
std::cout << y << std::endl;
}
int main()
{
foo(1);
foo('a');
foo(1.5);
foo(3.0);
}
输出1
, a
, 1.5
和1.5
。
在此示例中,您获得foo
三个独立的专业化: foo<int>
, foo<char>
和foo<double>
。 每个版本的foo
都有自己的y
版本,这意味着在此示例中存在三个不同的静态y
。 对每个专门化的第一次调用将初始化y
,随后的调用将不会重新初始化它。 在这种情况下,对foo(1.5)
调用会为foo<double>
初始化y
,但随后对foo(3.0)
调用则不会。
同样的情况也会发生,只是使用了不同的语法。
带有auto的Lamda只是一个带有重载为模板的operator()的类,并使用auto进行类型推导(遵循模板参数推导的规则)。
在这种情况下,静态y字段与该函数对象模板运算符的实例化一样多。
像手写类一样完成初始化,这是函数第一次被触发(在这种情况下为lambda)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.