的順序我知道C++繼承自C多的要求,其中之一是,除非它以前曾遇到過一個原型或定義這個函數,編譯器將無法識別全局函數。C++的困惑在函數重載和申報
這也影響C++函數重載。如果函數調用有多個候選者,那麼如果編譯器還沒有看到它的原型/定義,那麼「正確的」候選者將不會被包含在選擇過程中。
考慮:
void foo(int v)
{
cout << "Int version" << endl;
}
template <class T>
void call_foo(const T& v)
{
foo(v);
}
void foo(const std::string& v)
{
cout << "Overload for string" << endl;
}
這裏,call_foo(std::string("abc"))
通話將導致編譯器錯誤,即使是foo
爲std::string
過載。問題在於之前的函數模板call_foo
被定義爲編譯器看到過載。
然而,這似乎並不適用於全球運算符重載。我們定期重載std::ostream& operator << (std::ostream& os, const T&);
以使我們的自定義類型與C++ ostreams兼容。無論運算符重載函數在何處定義,編譯器都會選擇正確的重載。
例如:
struct Bar { };
template <class T>
void dispatch(const T& v)
{
std::cout << v << std::endl;
}
std::ostream& operator << (std::ostream& os, const Bar& b)
{
os << "Outputting Bar...";
return os;
}
在這裏,如果我們調用dispatch(Bar())
,編譯器調用正確的過載,輸出Outputting Bar...
。
所以,看來C++標準允許更高級的行爲,當談到選擇運算符重載候選函數。
我的問題是,爲什麼這種能力不能擴展到常規函數重載?我意識到需要與C向後兼容,但這不會對此產生任何影響,因爲只要您編寫函數重載,您就不會編寫C程序。
第二個'foo'不是專門化的,它是另一個重載名稱foo的函數。 – pmr
正確,已更正。 – Channel72
我不明白你的'operator <<'例子,因爲它與你的第一個例子沒有任何比較。沒有調度模板,只是各種重載。 – GManNickG