[英]Why does MSVC produce C3668 error when overriding function with correct signature?
[英]Why the Compiler does not detect correct function signature in error?
問題是參考這個 ,這是在不久前發布的。
盡管OP很樂意接受解決了他的問題的答案,但我對於為什么編譯器給出了看似錯誤的錯誤的細節感到有點興趣。
下面是我創建的一個小代碼示例,用於演示相同的代碼:
class YourClass
{
};
class YourClass2
{
};
class MyClass
{
public:
void doSomething(YourClass2 obj)
{
//Nothing more Interesting to do
}
};
int main()
{
YourClass *ptr = new YourClass();
MyClass obj;
obj.doSomething(ptr);
return 0;
}
編譯這與海灣合作委員會(4.3.4)給出了一個看似奇怪的錯誤的結果:
prog.cpp: In function ‘int main()’:
prog.cpp:23: error: no matching function for call to ‘MyClass::doSomething(YourClass*&)’
prog.cpp:13: note: candidates are: void MyClass::doSomething(YourClass2)
所以問題是:
為什么編譯器會處理呼叫,
obj.doSomething(ptr);
作為對原型的函數的調用,
MyClass::doSomething(YourClass*&)
並不是
MyClass::doSomething(YourClass*)
這似乎是一個明顯的例子。
首先,請注意表達式 ptr
(不是變量 ptr
)的類型為YourClass *&
。 這個很重要; 它是引用類型可以工作的唯一方式(否則,當你執行YourClass *&x = ptr
時,你將引用一個副本 ,這也是你的類YourClass *&x = (ptr + 1)
失敗的原因)。 因此,編譯器開始使用MyClass::doSomething(YourClass *&)
搜索函數。
當然,這個調用可以匹配原型MyClass::doSomething(YourClass *)
。 它也可以匹配MyClass::doSomething(const YourClass *)
或許多其他。 可能存在數十個(或者,具有多個參數,容易數百或數千個)可能與此調用匹配的原型; 然而,沒有人能找到。
所以編譯器放棄了,並給出了錯誤。 在錯誤中,而不是列出每個理論上可能的匹配,它引用了一個最接近它最初尋找的原型; 也就是說, MyClass::doSomething(YourClass *&)
。
正如其他人所說,編譯器試圖提供幫助,可能會使您感到困惑。 讓我們從最簡單的錯誤開始:
錯誤:沒有用於調用
obj.doSomething(ptr)
匹配函數
雖然錯誤消息是正確的,但它提供的信息非常有限。 在這個例子中,代碼很容易遵循,但考慮更復雜的代碼。 你閱讀了錯誤信息,你可能會想...... 什么是obj?,什么是ptr? 所以它試圖幫助你並告訴你obj
是什么:
錯誤:沒有匹配函數來調用'MyClass :: doSomething(ptr)'
好吧,那更好,它告訴你至少在你需要查找重載的類中,但考慮到類是std::ostream
和函數operator<<
...有太多的重載,仍然,什么是ptr
的類型? 所以它向前移動並試圖描述參數:參數是一個類型YourClass*
的左值 ...我已經看到過去產生的那種錯誤信息:
錯誤:沒有匹配函數來調用'MyClass :: doSomething',它將
YourClass*
左值作為參數。
好的,所以錯誤報告已經完成。 現在認為該函數可能有更多的參數,並且錯誤消息可以變成一個復雜的野獸(想象一下5的類型XXX的左值列表和一個類型為YYY的左值和......“)。 接下來的事情是使錯誤消息的語法同樣精確(參數的左值 - 重要性,或者右值 - 度將是重要的,因此必須存在一條信息)。 所以它再次重寫錯誤消息:
錯誤:沒有用於調用'MyClass :: doSomething(YourClass *&)'的匹配函數
問題是你試圖將其解釋為函數簽名,但它更像是函數調用的描述。
錯誤消息未在標准中定義,並且它們在一個編譯器之間不同,甚至在同一編譯器中從一個版本到另一個版本。 在一天結束時,您需要學習閱讀錯誤消息及其含義。
編譯器正試圖提供幫助。
MyClass::doSomething(YourClass*&)
這沒有命名任何函數:代碼中沒有與此匹配的函數。
YourClass*&
是您嘗試傳遞給名為MyClass::doSomething
的函數的參數的類型:參數( ptr
)是左值,由&
表示在錯誤中。
編譯器需要某種方法來區分左值參數和右值參數,以便為您提供盡可能多的有用診斷信息; 這是一種簡潔的方法。
編譯器不需要生成對您有意義的消息。 它需要告訴您代碼中存在錯誤。 現在它打印的消息是由編譯器決定的。 標准沒有說明它應該打印什么消息,什么不打印。 當編譯器打印錯誤消息時,在我看來,該錯誤消息可能是好的/有用的,或者是壞的/無用的,但不是“錯誤的”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.