Use decltype and std::function with lambda

2020-04-02 08:59发布

问题:

This works ...

auto x = 4;
typedef decltype(x) x_t;
x_t y = 5;

... so why doesn't this?

int j = 4;  
auto func = [&] (int i) { cout << "Hello: i=" << i << "  j=" << j << endl;};
typedef decltype(func) lambda_t;
lambda_t func2 = [&] (int i) { cout << "Bye: i=" << i << "  j=" << j << endl;};

... and how would I declare lambda_t manually using std::function?

回答1:

... so why doesn't this [work]?

Because each lexical instance of a lambda has a different type. It does not matter if the same characters are used.

.. and how would I declare lambda_t manually using std::function?

The lambda takes an int argument and does not return anything... Therefore:

typedef std::function<void(int)> lambda_t;


回答2:

Lambda types are unutterable (cannot be named), which is the reason you cannot do what you are asking. Besides that, each lambda is of a different type, so even if you could name the type, you would not be able to assign the second lambda to the first. If you think of the lambda syntax as a shortcut for a function object that becomes clearer: the member operator() is different for each lambda and thus they are of different types.

You can, on the other hand assign a lambda to a std::function<> object of the appropriate signature, which in your case would be std::function<void(int)>.



回答3:

Here's some solid proof that this doesn't work. Similar scenario:

int foo = 3;
int bar = 3;

std::cout << (typeid(foo).hash_code() == typeid(bar).hash_code()); // prints one -- obviously - they are the same type

Now, lets use the exact same code, but with lambdas. What do you think the response will be.

  auto foo = [](){std::cout << "HELLO\n"; };

  auto bar = [](){std::cout << "HELLO\n"; };

  std::cout << (typeid(foo).hash_code() == typeid(bar).hash_code()); // prints 0 -- different type even though they are declared exactly the same.