2017-01-30 94 views
-1

https://godbolt.org/g/kNlYxl为什么VC++编译这段代码,同时锵不会

锵版本: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"; 
} 
+0

如果你想询问这个错误,你需要发布代码来重现这个错误,“从const char [5]'没有已知的转换为'第一个参数''。这段代码没有。 –

+1

您只能得到*一个*用户定义的转换,并且您的代码要求*两个*:一个从'“test”到'A',另一个从'A'到'B'。 –

+0

@nm用clang 3.9.1来看看上面的godbolt例子,并看看clang所显示的提示。 – cageman

回答

4

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

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

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

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

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

+1

您能否详细说明具体的扩展,以及为什么clang说第一个参数没有从'const char [5]'到'A'的已知转换。谢谢! – cageman

+0

事实上,[Microsoft和C + +的扩展](https://msdn.microsoft.com/en-us/library/34h23df8.aspx)似乎都不适用。这个清单不完整吗? – IInspectable

+0

请加上实际的原因,这是非法的C++(Kerrek在上面评论说,由于某种原因) –