11

I read somewhere that a lambda function should decay to function pointer if the capture list is empty. The only reference I can find now is n3052. With g++ (4.5 & 4.6) it works as expected, unless the lambda is declared within template code.

For example the following code compiles:

void foo() {
    void (*f)(void) = []{};
}

But it doesn't compile anymore when templated (if foo is actually called elsewhere):

template<class T>
void foo() {
    void (*f)(void) = []{};
}

In the reference above, I don't see an explanation of this behaviour. Is this a temporary limitation of g++, and if not, is there a (technical) reason not to allow this?

Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
rafak
  • 5,501
  • 2
  • 19
  • 30
  • 1
    Note that N3052, which you cite, was indeed incorporated into the C++0x FCD (N3092 5.1.2/6). Visual C++ 2010 does not implement the conversion at all (unsurprising, since the language permitting it was incorporated into the standard so soon before VC++ was released). I've submitted a bug report on Microsoft Connect concerning that (though I anticipate it won't be fixed until the next release of Visual C++): https://connect.microsoft.com/VisualStudio/feedback/details/572138/visual-c-2010-does-not-permit-conversion-of-captureless-lambda-to-function-pointer – James McNellis Jul 01 '10 at 13:44
  • Just as an FYI: None of the above code is supported in Intel C++ 11.1 – Jamie Cook Jul 09 '10 at 07:21
  • 1
    Its already in GCCs bugtracker, though as of now unconfirmed: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45080 – Georg Fritzsche Aug 06 '10 at 04:21
  • @James Noob question (also to questioner). Given that a function pointer capture list is empty for a collection of lambdas, can we store these in a container without using std::function (expensive for cases i've come across...)? It's been two years sorry about that, just stumbled on this page and was curious... – woosah Mar 19 '13 at 02:43

1 Answers1

4

I can think of no reason that it would be specifically disallowed. I'm guessing that it's just a temporary limitation of g++.

I also tried a few other things:

template <class T>
void foo(void (*f)(void)) {}

foo<int>([]{});

That works.

typedef void (*fun)(void);

template <class T>
fun foo() { return []{}; } // error: Cannot convert.

foo<int>()();

That doesn't (but does if foo is not parameterized).

Note: I only tested in g++ 4.5.

Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • Yes, in the first case the lambda is declared in a non-template portion of code (although it is used by a template function). The same problem happens when the lambda is declared inside a template class. – rafak Jul 01 '10 at 08:44