Question: I have a very strange problem. To keep things simple, lets say I want to have a function which takes 2 functions with the same declaration as arguments

```
template<typename Func>
void foo(Func a, Func b)
{
    std::cout << "good";
}

```

To try things out I took `putchar` from cstdio, and created an identical function to match the `putchar`.

```
int myPutcharFunc(int)
{
    return 0;
}

int main()
{
    auto myPutcharLambda = [](int) -> int
    {
        return 0;
    };

    foo(putchar, myPutcharFunc); // okay
    foo(putchar, myPutcharLambda);  //deduced conflicting types for parameter 'Func' ('int (__attribute__((__cdecl__)) *)(int)' and 'main()::<lambda(int)>')
}

```

Now, the lambda does not want to compile (the key is I want to use lambda capture).

So lets add template specialization, because the programmer is wiser than the machine, right? :)

```
template<typename Func>
void foo(Func a, Func b)
{
    std::cout << "good";
}

template<>
void foo(int(*)(int), int(*)(int))
{
    std::cout << "good";
}

```

No luck, the same error - why?
But for some reason, when I comment out the template specialization:

```
//template<>
void foo(int(*)(int), int(*)(int))
{
    std::cout << "good";
}

```

The code compiles. I obviously do not want to overload `foo` for EVERY set of function's arguments - thats what templates are for. Every step was tested both with msvc++ and g++. What am I doing wrong?

Answer: 
Every lambda is a different type, so you'll need to have two different template parameters to get them

```
template<typename FuncA, typename FuncB>
void foo(FuncA a, FuncB b)

```

Types don't decay when deducing template types (SEE COMMENT FOR CORRECTION). So a lambda remains a lambda and doesn't decay to a function pointer. Same reason a string literal is deduced as a `char[N]` instead of a const `char *`.

With your second example using specialization, it doesn't want to use your specialization, since the lambda is not a function pointer. You can cast the Lambda to a function pointer and make it work: <https://godbolt.org/g/ISgPci> The *trick* you can do here is say +my\_lambda because + is defined for pointers so it will force the non-capturing lambda to become a function pointer.
A lambda has its own type which can decay to a function pointer but not in the case of a template function match, it will for the real function as you found because of the implicit conversion. 

In the case of matching to a template you need to disambiguate and explicitly instantiate foo with the type you want or convert the lambda to a function pointer.

```
foo<decltype(putchar)>(putchar, myPutcharLambda);

```

or

```
foo(putchar, +myPutcharLambda);

```