10

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?

learnvst
  • 15,455
  • 16
  • 74
  • 121

3 Answers3

14

... 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;
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
8

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)>.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • You can certainly typedef lambdas with decltype like that. – R. Martinho Fernandes Nov 29 '12 at 18:14
  • 1
    @R.MartinhoFernandes begs the question why `decltype(func)` doesn't return `std::function` instead of some unusable garbage? – learnvst Nov 29 '12 at 18:17
  • 1
    @learnvst: Why should it? `decltype` returns the declared type, and a lambda is *not* a `std::function`. Also, `std::function` has performance implications amongst other things, thanks to type-erasure. – Xeo Nov 29 '12 at 18:28
  • 2
    @learnvst: It's not unusable garbage. But I have answered your question before http://stackoverflow.com/questions/11628765/why-do-lambda-functions-in-c11-not-have-function-types/11629125#11629125 – R. Martinho Fernandes Nov 29 '12 at 19:29
0

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.
Russell Greene
  • 2,141
  • 17
  • 29