Frage

Betrachten Sie den folgenden Code ein:

#include <stdio.h>

namespace Foo {
  template <typename T>
  void foo(T *, int) { puts("T"); }

  template <typename T>
  struct foo_fun {
    static void fun() { foo((T *)0, 0); };
  };
}

namespace Foo {
  void foo(int *, int) { puts("int"); }
}

using namespace Foo;

int main() {
  foo_fun<int> fun;
  fun.fun();
}

Was ist die erwartete Ausgabe? "T" oder int?

Ein Compiler (gcc 4.0.1 von Apples Xcode 3.1.2) Ausgang "int", zwei andere Compiler (gcc 4.1.2 und 4.1.3) Ausgang "T".

Wenn ich foo (int *, int) Deklaration / Definition vor der foo (T *, int) Version, die alle Ausgänge "int" bewegen. Ist die Reihenfolge der Überlastung / Spezialisierung in diesem Fall durch die aktuellen Standards definiert?

War es hilfreich?

Lösung

Die zweite void foo(... ist eine Überlast (und keine Spezialisierung), die bei der Definition von foo_fun::fun nicht sichtbar ist, so dass es nicht in Zusammenhang mit der Schablonendefinition gefunden wird. Da T* eine abhängige Art ist, die Auflösung von foo im Ausdruck foo((T*)0, 0) wird bis Vorlage Instanziierung Zeit und der Kontext der Instanziierung wird auch in Betracht gezogen wird verzögert werden. Allerdings 14.6.4.2 der Norm sagt, dass, wenn der Name der Funktion ist ein unqualifizierte-id , aber nicht eine Template-id dann für Nicht-ADL-Lookup funktioniert nur sichtbar bei der Punkt der Definition der Vorlage berücksichtigt. Es gibt keine Funktionsargumente vom Foo Namespace so kein Argument abhängige Lookup auftritt, damit die Template-Version von foo genannt wird und nicht die Nicht-Template-Überlastung.

Vielen Dank an diese Antwort für die Korrekturen litb.

Wenn Sie es eine Spezialisierung, wie unten gemacht, dann als Spezialisierungen bei Vorlage Instanziierung Zeit gewählt werden, kann die Spezialisierung so lange aufgerufen werden, da die entsprechende Spezialisierung auf dem Punkt zu sehen ist, bei der die Funktionsvorlage zunächst für int instanziiert wird.

namespace Foo {
    template<>
    void foo<int>(int *, int) { puts("int"); }
}

Kapitel 14 des aktuellen Standard, aber es ist nicht sehr gut lesbar:)

Edit: Wenn ich den relevanten Teil des Standard wählen hätte, würde es wahrscheinlich 14,6 [temp.res] para 9. (Ein wenig abgekürzt), wenn ein Name auf einem Template-Parametern hängt nicht , eine Erklärung für diesen Namen ist an dem Punkt in ihrem Umfang sein an, wo der Name in der Template-Definition erscheint; der Name auf die Erklärung zu diesem Zeitpunkt und diese Bindung nicht beeinträchtigt wird durch Erklärungen, die an der Stelle der Instanziierung sichtbar sind.

gefunden gebunden ist

Bearbeiten, edit: Aber Sie müssen auch berücksichtigen, 14.6.4.2 [temp.dep.candidate] nehmen. Es ist sehr schwierig und gefährlich zu versuchen, die Standard-Referenz, weil alle Abhängigkeiten, diese Antwort ist ein typischer Fall.

Andere Tipps

Als allgemeine Regel von zwei Versionen eines Compilers, der später ist wahrscheinlicher, mehr Standard.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top