-1

https://godbolt.org/g/kNlYxl

Clang version: X86-64 clang 3.9.1
VC++ version: x86-64 CL 19 RC

I would expect that it would compile since const char* is implicitely convertible to A and A is convertible to B. The interesting thing is that clang states that const char [5] is not convertible to A? Note: i understand now its not standard behavior, but i would still like to know the reason why VC++ accepts this code, i.e. which language extension is causing it?

Error given by clang:

no viable conversion from 'const char [5]' to 'B'

Hints given by clang:

note: candidate constructor not viable: no known conversion from 'const char [5]' to 'A' for 1st argument   
note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const char [5]' to 'const B &' for 1st argument
#include <string>
#include <vector>

struct A
{
  std::string m_test;
  A(const char* test)
    : m_test(test)
  {

  }
};

struct B
{
  A m_a;
  B( A a )
    : m_a(a)
  {

  }
};

int main()
{
  B test = "test";
}
rustyx
  • 80,671
  • 25
  • 200
  • 267
cageman
  • 333
  • 2
  • 10
  • `no known conversion from const char [5]' to 'A' for 1st argument` if you want to ask about this error, you need to post code that reproduces this error. This code doesn't. – n. m. could be an AI Jan 30 '17 at 12:21
  • 1
    You only get *one* user-defined conversion, and your code is asking for *two*: one from `"test"` to `A`, and one from `A` to `B`. – Kerrek SB Jan 30 '17 at 12:22
  • @nm Have a look at the godbolt example above with clang 3.9.1 and look at the hints shown by clang. – cageman Jan 30 '17 at 12:25
  • 1
    Possible duplicate of [Multiple implicit conversions on custom types not allowed?](http://stackoverflow.com/questions/12847272/multiple-implicit-conversions-on-custom-types-not-allowed) – user1810087 Jan 30 '17 at 12:26
  • Sorry misread the code. Clang says `note: candidate constructor not viable: no known conversion from 'const char [5]' to 'A' for 1st argument` because it excludes user-defined conversions from consideration, and that's because it's trying to resolve a different user-defined conversion. – n. m. could be an AI Jan 31 '17 at 08:16

1 Answers1

4

Only one implicit user-defined conversion is allowed, see [class.conv]/4:

At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.

So it seems to be a Microsoft C++ extension, indeed, if you disable MSVC extensions (/Za), you'll get the same error:

error C2440: 'initializing': cannot convert from 'const char [5]' to 'B'

As to the reason why - it looks like some kind of a "multiple implicit conversions" extension, but there is no mention of it in documentation. There was even a bug submitted, and it was supposed to be fixed, but I guess that didn't work out.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
rustyx
  • 80,671
  • 25
  • 200
  • 267
  • 1
    Could you elaborate on the specific extension and why clang says no known conversion from 'const char [5]' to 'A' for 1st argument. Thanks! – cageman Jan 30 '17 at 12:21
  • Indeed, none of the [Microsoft Extensions to C and C++](https://msdn.microsoft.com/en-us/library/34h23df8.aspx) seems to apply. Is this list incomplete? – IInspectable Jan 30 '17 at 12:27
  • Please add the actual reason this is illegal C++ (Kerrek stated it in comments above, for some reason) – Lightness Races in Orbit Jan 30 '17 at 12:44
  • Thanks so far, lets see what the microsoft guys have to say. See: https://connect.microsoft.com/VisualStudio/feedback/details/3119953 – cageman Jan 30 '17 at 14:34