2017-01-30 87 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在上面評論說,由於某種原因) –