2

I can declare anonymous functions (they are the same as lambda, but without "context" - [...]) without auto easily:

#include <iostream>

using namespace ::std;

void foo(void (*f)(char))
{
    f('r');
}

int main()
{
    void (*anon)(char) = [](char c) -> void { cout << c << endl; };
    foo(anon);
    return 0;
}

But how to declare lambda ? Is it the only possible way? (maybe with typedef). Here I use ::std::function, but I didn't mention context of f somewhere in foo arguments...:

#include <iostream>
#include <functional>

using namespace ::std;

//int foo(auto f, char x) // !only since c++14
int foo(function<int(char)> f, char x)
{
    return f(x+1);
}

int main()
{
    int a = 5, b = 10;

    //void (*lambda)(char) = [](char c) { cout << c << endl; };
    //auto sample_lambda = [&a,b](char c) -> int // !only since c++11
    function<int(char)> sample_lambda = [&a,b](char c) -> int  
        {
            for (;a<b;a++)
                cout << a << c << endl;
            return (int)c+a; 
        };

    foo(sample_lambda, 's');
    return 0;
}
yanpas
  • 2,155
  • 1
  • 17
  • 26
  • define foo as a template function. `template void foo(Function&& f) { f('r'); }` – Richard Hodges Jan 04 '16 at 14:33
  • 1
    "Declaring a lambda" doesn't make sense. A lambda is a type of *expression*, and you cannot delcare expressions, no more than you can, say, "declare a sum" or "declare a function call". – Kerrek SB Jan 04 '16 at 14:34
  • 2
    A non-capturing lambda expression can decay to a pointer to a function, but it *isn't* a pointer to a function. – Some programmer dude Jan 04 '16 at 14:41

2 Answers2

5

You can't.

The type of a closure is a unique, unnamed type. Your first example works because closure types have a conversion function to a pointer-to-function if they don't capture anything, not because the closure is a void (*) (char).

You are best to just stick with auto as std::function can have additional overhead for the type erasure.

TartanLlama
  • 63,752
  • 13
  • 157
  • 193
0

auto as parameter is an extension provided by GCC and others. What you can do instead is to use templates:

template<typename T>
int callFoo(T funct, int x) {
    return funct(x+1);
}
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141