2017-12-08 1 views
1

Hier zweiphasige Namenssuche für Vorlage aus Iso-Norm:stragety der Name Nachschlagen über volle Spezialisierung der Funktion?

  • Wenn für die Deklaration eines Namens in einer Template-Definition, die üblichen Suchregeln (6.4.1, 6.4 verwendet suchen. 2) werden für nicht abhängige Namen verwendet.

    #include <iostream> 
    
    void WithoutTemplate(int) {std::cout << "NonTemplate: int\n";} 
    
    template<typename T> 
    void WithTemplate(T) {std::cout << "no match\n";} 
    
    template<> 
    void WithTemplate(int) {std::cout <<"Template: int\n";} 
    
    template<typename T> 
    void test(T) 
    { 
        WithTemplate(1.1); 
        WithoutTemplate(1.1); 
    } 
    
    void WithoutTemplate(double) {std::cout << "nontemplate: double\n";} 
    
    template<> 
    void WithTemplate(double) {std::cout << "template: double\n";} 
    
    int main() 
    { 
        test(1.1); 
    } 
    

    Ausgabe:

  • bekannt ist

Beispielcodes

  • Das Nachschlagen von Namen auf den Template-Parametern abhängig ist, bis die tatsächliche Vorlage Argument verschoben

    Vorlage: Doppel NonTemplate : Int

    zwei Funktionen sind: WithTemplate und WithoutTemplate. Der Parameter 1.1 ist nicht abhängig (obwohl es prvalue ist, die keinen Namen hat? Ich nehme an, es immer noch nicht-abhängige Regeln Namen gehorchen)

    • -Namen-Suche von WithoutTemplate trifft 2-Phasen-Lookup, denn wenn WithoutTemplate(1.1) Aufruf void WithoutTemplate(double) ist nicht sichtbar. So ist der Ausgang NonTemplate: int einfach zu verstehen.
    • Allerdings verwirrt mich der Fall, der die volle Spezialisierungsfunktion aufruft. sein Verhalten ist entgegengesetzt zu den Regeln des Standards (2-Phasen-Suche). Ich dachte es sollte template: int
    • ausgeben

    Also, gibt es andere Namen Suchregeln für die Spezialisierung? Oder etwas anderes, das ich falsch verstehe? Hier

    ist, was ich habe:

  • +1

    Zweiphasige Namenssuche ist hier nicht relevant; Ihre Vorlagendefinition verwendet keine abhängigen Namen - der einzige Name, den Sie verwenden, ist 'std :: cout', der vollständig qualifiziert ist. (1.1 ist kein Name.) –

    +0

    @AlanStokes Ich glaube 'WithoutTemplate' verwendet hier 2-phasige Namenssuche, die auch einen nicht abhängigen Namen verwendet. Also 'WithTemplate' kann es auch verwenden, aber ich bin mir nicht sicher, also ist die Frage 'stratety ...' – czxyl

    +0

    Die Namen, die in' test' nachgeschlagen werden, sind nicht abhängig, daher gelten die normalen Regeln. An der Stelle, an der Sie 'WithoutTemplate' aufrufen, ist nur eine Definition sichtbar, also die, die aufgerufen wird. (Wenn Sie "1.1" durch "(T) 1.1" ersetzen, sehen Sie möglicherweise andere Ergebnisse.) –

    Antwort

    4

    Ihr Programm hat Verhalten nicht definiert, weil Sie die explizite Spezialisierung von WithTemplate<double> definieren, nachdem es gewesen ist implizit durch den Aufruf instanziiert WithTemplate(1.1). Explizite Spezialisierungen müssen vor jeder Verwendung erscheinen, die Instanziierung verursachen würde - siehe z.B. http://en.cppreference.com/w/cpp/language/template_specialization.

    Es hat also keinen Sinn, das Verhalten mit dem zu vergleichen, was der Standard sagt; Der Standard sagt explizit nichts darüber aus, was hier geschehen soll.

    Verwandte Themen