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?
 
    