-1

consider some code:

void foo() { }
bool bar() { return true; }

struct S
{
    void operator=(std::function<void()> f){f();};
    void operator=(std::function<bool()> f){f();};      
};

int main() {
    S s;
    s = foo; // ok
    s = bar; // error: use of overloaded operator '=' is ambiguous
}    

How can I make this example unambiguous?

Barry
  • 286,269
  • 29
  • 621
  • 977
Ace shinigami
  • 1,374
  • 2
  • 12
  • 25
  • Maybe I am missing something, but how does `S = bool()` match the `void` version of `operator=`? And I assume by `S = void()` and `S = bool()` you actually mean something more like `S s; s = foo;` and `S s; s = bar;`, right? – Remy Lebeau Apr 25 '16 at 20:09
  • Can you make this an [mcve] and include the error message that you are getting? – NathanOliver Apr 25 '16 at 20:12
  • @RemyLebeau, it does, because `std::function` does type erasure – WhiZTiM Apr 25 '16 at 20:13
  • @RemyLebeau yes I do mean something more like `S s; s = foo;` and `S s; s = bar;` as for how `S = bool()` matches `void operator=(std::function f){};` I am not sure but when I execute the code it gives me I get the `error ambiguous overload for 'operator='` – Ace shinigami Apr 25 '16 at 20:28

1 Answers1

2

The problem you're running into is that std::function<void(Args...)> is allowed to discard return types - so both std::function<void()> and std::function<bool()> can be constructed from a bool(*)(). The latter will forward through the return from bar, but the former will just discard it. That's perfectly valid behavior, but causes this to be ambiguous.

What you probably want is to avoid std::function altogether:

template <class F>
void operator=(F f) { f(); }
Barry
  • 286,269
  • 29
  • 621
  • 977
  • what if I want to have each function return something different? Explicit template specialization would be my solution but then I have to use plain function pointers right? – Ace shinigami Apr 25 '16 at 21:48
  • @Julian That depends entirely on what it is you actually want to do. – Barry Apr 25 '16 at 22:06