为什么VC++编译这段代码,而Clang不会

Why does VC++ compile this code while Clang won't

本文关键字:Clang 不会 代码 编译 VC++ 段代码 为什么      更新时间:2023-10-16

https://godbolt.org/g/kNlYxl

叮当

版本:X86-64 叮当3.9.1
VC++ 版本:x86-64 CL 19 RC

我希望它会编译,因为 const char* 隐式转换为 A,而 A 可转换为 B。有趣的是,clang 声明 const char [5] 不能转换为 A?注意:我现在明白它不是标准行为,但我仍然想知道 VC++ 接受此代码的原因,即是哪种语言扩展导致了它?

叮当声给出的错误:

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

叮当当给出的提示:

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";
}

只允许一个隐式用户定义的转换,请参阅 [class.conv]/4:

最多一个用户定义的转换(构造函数或转换函数)隐式应用于单个值。

所以它似乎是一个Microsoft C++扩展,事实上,如果你禁用MSVC扩展(/Za),你会得到同样的错误:

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

至于原因 - 它看起来像某种"多次隐式转换"扩展,但在文档中没有提到它。甚至提交了一个错误,它应该被修复,但我想这没有解决。