Is it safe to assume that identical lambda express

2019-06-15 13:40发布

I am experimenting with lambdas and the fact that different lambda expressions have different types, even though they are the same. Consider this code

#include <iostream>

template <typename T> void once(T t){
    static bool first_call = true;
    if (first_call) t();
    first_call = false;
}

int main() {    
    int counter = 0;
    auto a = [&counter](){counter++;};
    once(a);
    once(a);
    std::cout << counter;              // 1

    auto b = a;                        // same type
    once(b);
    std::cout << counter;              // 1

    auto c = [&counter](){counter++;}; // different type
    once(c);
    once(c);               
    std::cout << counter;              // 2
}

This prints 112, ie a and b are of course of same type and c has a different type.

Is the compiler allowed to let c be of the same type than a?

I mean the expressions are identical and it would be an obvious optimization.

PS: In case the capture prevents such an optimization, then what about lambdas without capture?

related: what is the type signature of a c++11/1y lambda function? and Can the 'type' of a lambda expression be expressed?

1条回答
姐就是有狂的资本
2楼-- · 2019-06-15 14:18

Is the compiler allowed to let c be of the same type than a?

No. [&counter](){counter++;} is a lambda expression and per [expr.prim.lambda.closure]/1:

The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type, whose properties are described below.

So, for each lambda expression, even if it is identical to a previous one, you will get a unique type.

查看更多
登录 后发表回答