Betrachten Sie den folgenden Code ein:Warum ändert die Verwendung des Scope-Resolution-Operators, welche überlastete Vorlage im globalen Namespace aufgerufen wird?
#include <iostream>
template <class W, class T>
void foo(W& a, T& t)
{
std::cout << "generic" << std::endl;
}
template <template <bool> class W, class T>
void foo(W<true>& a, const T& t)
{
foo(a, const_cast<T&>(t));
}
template <class W>
void foo(W& a, int& t)
{
std::cout << "int" << std::endl;
}
template <bool> struct what;
template<> struct what<true> { };
int main() {
const int ci = 10;
what<true> wt;
foo(wt, ci);
return 0;
}
Der Ausgang ist (ideone link):
int
Das macht Sinn für mich: foo(what<true>&, const int&)
entspricht der const_cast
Überlastung, die dann foo(what<true>&, int&)
aufruft, die die int
Überlastung Spiele .
Doch wenn ich ändern, um die const_cast
Funktion auf die folgenden:
template <template <bool> class W, class T>
void foo(W<true>& a, const T& t)
{
::foo(a, const_cast<T&>(t));
}
Der Ausgang ist jetzt (ideone link):
generic
Das macht keinen Sinn für mich. Warum bewirkt das Ändern der const_cast
Überladung von foo
, ::foo
aufzurufen, dass die generische Version anstelle der int-Version aufgerufen wird?
Mein Verständnis von ::
ist, dass es nur zu disambiguieren war, welche Funktion aufgerufen wird, wenn Sie eine Methode oder eine Funktion im globalen Namespace haben. Die Überlastung const_cast
stimmt immer noch überein, die dann ::foo(what<true>&, int&)
aufrufen sollte, die der int
Spezialisierung entsprechen sollte - sollte es nicht?
Ferner kann, wenn ich den Auftrag und legen Sie die const_cast
Überlastung mit ::foo
nach der int
Spezialisierung ändern, dann ist die int
Spezialisierung wird aufgerufen (ideone link). Warum spielt hier die Reihenfolge der Definition eine Rolle?