繁体   English   中英

C ++ 14中通用Lambda中的静态自动变量

[英]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中编译,并且工作正常。 但是,考虑到变量ystatic

  • 变量y的类型是什么? 每次调用lambda时y的类型都会改变吗?
  • 尽管是static变量y是否在每个调用中都初始化了吗? 注释的// y = x不需要更新变量y的值。
  • 此行为符合C ++ 14 Standard吗?

如果我在每个调用中打印sizeof(y) ,则分别得到4、1、8和16。

关于C ++中的局部和全局静态变量

您的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);
}

输出1a1.51.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM