2
struct myclass
{
    myclass(void(*)()) {}
};

void test1(void(*)()) {}
void test2(myclass) { }
void cb() {}

int main()
{
    test1(cb);      // works
    test2(cb);      // works
    test1([](){});  // works

    test2([](){});  // does not work, why? there's no "explicit" keyword next to myclass.

}

Why this doesn't work?

The following obviously works but I don't want to use it.

     test2(myclass([]{}));

Notes: I do not want to accept a std::function<void()>> and I don't want to create a template<T> myclass(T f) {} either.

Gam
  • 1,244
  • 1
  • 8
  • 16

2 Answers2

3

You can only have one user defined conversion - and lambda to function pointer counts as user defined. Instead use some sorcery to do the function pointer conversion explicitly:

test2(+[](){}); 

Note also that the parens in a nullary lambda are optional, so this also works:

test2(+[]{}); 
Community
  • 1
  • 1
Barry
  • 247,587
  • 26
  • 487
  • 819
2

You can only have one user-defined conversion in a conversion sequence. Try:

test2(static_cast<void(*)()>([](){}));

Or:

test2(static_cast<myclass>([](){}));
Kerrek SB
  • 428,875
  • 83
  • 813
  • 1,025
  • Upvoted for the user defined conversion answer. Simply accepted Barry's one since it was a bit more complete (it had the + "sorcery" in it), which is sick since I had absolutely no idea about it. – Gam May 13 '16 at 20:51