【问题标题】:Why does VC++ compile this code while Clang won't为什么 VC++ 编译这段代码而 Clang 不会
【发布时间】:2017-01-30 12:14:05
【问题描述】:

https://godbolt.org/g/kNlYxl

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

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

clang 给出的错误:

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

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

【问题讨论】:

  • no known conversion from const char [5]' to 'A' for 1st argument 如果您想询问此错误,您需要发布重现此错误的代码。这段代码没有。
  • 你只得到 one 用户定义的转换,并且你的代码要求 two:一个从 "test"A,和一个从AB
  • @nm 看看上面带有clang 3.9.1的godbolt示例,看看clang显示的提示。
  • 抱歉误读了代码。 Clang 说 note: candidate constructor not viable: no known conversion from 'const char [5]' to 'A' for 1st argument 是因为它不考虑用户定义的转换,这是因为它试图解决不同的用户定义的转换。

标签: c++ visual-c++ clang++


【解决方案1】:

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

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

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

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

至于原因 - 它看起来像是某种“多重隐式转换”扩展,但文档中没有提及它。甚至还有一个bug submitted,它应该被修复,但我想这没有成功。

【讨论】:

  • 您能否详细说明具体的扩展以及为什么 clang 说第一个参数没有从 'const char [5]' 到 'A' 的已知转换。谢谢!
  • 确实,Microsoft Extensions to C and C++ 似乎都不适用。这个列表不完整吗?
  • 请添加这是非法 C++ 的实际原因(Kerrek 在上面的 cmets 中说明了这一点,出于某种原因)
  • 谢谢到目前为止,让我们看看微软的家伙有什么要说的。见:connect.microsoft.com/VisualStudio/feedback/details/3119953
猜你喜欢
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
  • 2013-08-08
  • 1970-01-01
相关资源
最近更新 更多