默认实参内声明的Lambda是否每次调用的类型都不同?求标准依据
问题与代码示例
#include <iostream> int foo(int x = [](){ static int x = 0; return ++x; }()) { return x; }; int main() { std::cout << foo() << foo(); // prints "12", not "11" }
已知C中默认实参会在每次函数调用时求值,那么这是否意味着每次调用时该Lambda的类型都不相同?请给出C标准中的相关条款来解释此行为。
解答
结论:每次调用时该Lambda对应的闭包类型是相同的
默认实参的“每次调用求值”指的是Lambda表达式的调用操作(即()执行过程)会重复触发,但Lambda本身对应的闭包类型并不会因为求值次数改变而变化。
标准条款依据
根据C++标准中[expr.prim.lambda.closure](闭包类型)的条款:
每个lambda表达式都会关联一个唯一的、未命名的非联合类类型(闭包类型)。同一个lambda表达式在同一翻译单元中多次出现时,会引用同一个闭包类型。
也就是说,代码里的这个Lambda表达式,不管在默认实参中被求值多少次,它对应的闭包类型始终是同一个。
代码行为的本质
代码中输出12的原因是:Lambda函数体里的static int x属于闭包类型的调用操作符函数的静态变量——静态变量的生命周期贯穿整个程序,只会被初始化一次。每次默认实参求值时,都会调用该闭包类型的operator(),从而递增这个静态变量的值,因此两次调用foo()分别得到1和2,最终输出12。
内容的提问来源于stack exchange,提问作者cppbest
相关产品推荐
相关产品推荐

