This program is compiled by clang:
#include <mutex>
int main() {
std::mutex mtx;
const std::lock_guard<std::mutex>& lock(mtx);
return 0;
}
Other major compilers refuse it (I have tried gcc, msvc, and icc). This is an error message from gcc:
error: invalid initialization of reference of type ‘const
std::lock_guard<std::mutex>&’ from expression of type ‘std::mutex’
Others give similar errors.
Is clang right or wrong? Can this be reproduced with a simpler example not involving library classes? I have tried but to no avail.
Edit this seems to be the minimal reproduction:
struct A {};
struct X
{
explicit X(A&) {};
};
int main()
{
A a;
const X& x(a);
}
Interestingly, an int
in place of A
does trigger the error message in clang (which is why I could not reproduce this initially).
I don't have the relevant chapter and verse of the C++ standard; I can only refer to CppReference on Converting Constructors right now (emphasis mine):
A constructor that is not declared with the specifier explicit and which can be called with a single parameter (until C++11) is called a converting constructor.
Unlike explicit constructors, which are only considered during direct initialization (which includes explicit conversions such as static_cast), converting constructors are also considered during copy initialization, as part of user-defined conversion sequence.
So:
struct A {};
struct X
{
explicit X(A const &) {};
};
int main()
{
A a;
const X& x1(A()); // OK, direct init (no A object after init)
const X& x3(a); // NOK, copy init
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With