I've discovered a discrepancy between the Microsoft Visual C++ compiler, and gcc-4.8.1 (as provided by ideone.com). Consider the following SSCCE:
struct S
{
int x;
};
class A
{
public:
int x;
A(const S& s) : x(s.x) {}
};
class B
{
int x, y;
public:
template <typename T> explicit B(const T& t) : x(t.x), y(t.y) {}
B(const A& a) : x(a.x), y(0) {}
};
int main() {
S s = {1};
B b1 = s; // Compiles OK on MSVC++;
// Fails on gcc - conversion from ‘S’ to non-scalar type ‘B’ requested
B b2(s); // Fails on both - Error: y is not a member of S in B::B<S>(const T &)
}
I understand why the line B b2(s);
fails - the explicit
constructor matches so it's tried; but t.y
doesn't exist. Fine.
But I can't work out whether MSVC++ is correct in allowing B b1 = s;
, or whether gcc is correct in rejecting it. MSVC++ is constructing a temporary from A::A(const S&)
, and using that to initialise b1
via B::B(const A&)
; I'm not sure why gcc errors.
Which compiler's right?
(As an after note, if I remove the explicit
both compilers reject B b1 = s;
- presumably because the templated constructor is now fair game for the implicit construction of the temporary.)
Edit: From the comments, it appears the MSVC++ also rejects the B b1 = s;
line in Visual Studio 2012, so the consensus seems to be it really is an error. In which case - what is the nature of the error? What does that error message mean?