I'm trying to write a class with overloaded constructors that accept std::function objects as parameters, but of course every damn thing can be implicitly cast to a std::function of any signature. Which is really helpful, naturally.

Example:

class Foo {
  Foo( std::function<void()> fn ) {
    ...code...
  }
  Foo( std::function<int()> fn ) {
    ...code...
  }
};

Foo a( []() -> void { return; } );    // Calls first constructor
Foo b( []() -> int { return 1; } );   // Calls second constructor

This won't compile, complaining that both constructors are essentially identical and ambiguous. Which is nonsense, of course. I've tried enable_if, is_same and a bunch of other things. Accepting function pointers is out of the question, because that would prevent the passing of stateful lambdas. Surely there must be a way to achieve this?

My templating skills are a little lacking, I'm afraid. Normal template classes and functions are easy enough, but playing silly buggers with the compiler is a little out of my league. Can someone help me out, please?

I know variants of this question have been asked before, but they generally focus on normal functions rather than constructors; or overloading by arguments instead of return types.

Edit
Report