Why doesn't this code compile?
#include <functional>
struct S { S(std::function<void()>) { } };
int main()
{
S a([]() {}); // compiles
S b = []() {}; // doesn't compile (except pre-C++20 on MSVC!)
}
Clang's error:
error: no viable conversion from '(lambda at <source>:6:8)' to 'S'
| S b = []() {}; // doesn't compile (except pre-C++20 on MSVC!)
| ^ ~~~~~~~
note: candidate constructor not viable: no known conversion from '(lambda at <source>:6:8)' to 'std::function<void ()>' for 1st argument
| struct S { S(std::function<void()>) { } };
| ^ ~~~~~~~~~~~~~~~~~~~~~
Lets put std::function
and lambdas aside, because the issue is more general, and look at a simpler example:
struct A {};
struct B {
B(A) {}
};
struct C {
C(B) {}
};
int main() {
C c1(A{}); // I
C c2 = A{}; // II
}
I
is ok but II
fails with:
<source>:15:7: error: no viable conversion from 'A' to 'C'
(Full error here: https://godbolt.org/z/GYbezWEG5)
The reason is that only a single user provided conversion is taken into account.
C c1(A{})
requires to convert A
to B
to call the constructor of C
. This is ok.
C c2 = A{};
on the other hand would require to first convert the A
to B
and then B
to C
. This is not ok.
For more details I refer you to cppreference.