2010-10-14 23 views
13

Während this lesen, ich bin verwirrt durch die folgenden Beispiele:Funktion Vorlage Spezialisierung

// Example 2: Explicit specialization 
// 
template<class T> // (a) a base template 
void f(T); 

template<class T> // (b) a second base template, overloads (a) 
void f(T*);  //  (function templates can't be partially 
        //  specialized; they overload instead) 

template<>  // (c) explicit specialization of (b) 
void f<>(int*); 

// ... 

int *p; 
f(p);   // calls (c) 

Hier (c) ist eine explizite Spezialisierung von (b).

// Example 3: The Dimov/Abrahams Example 
// 
template<class T> // (a) same old base template as before 
void f(T); 

template<>  // (c) explicit specialization, this time of (a) 
void f<>(int*); 

template<class T> // (b) a second base template, overloads (a) 
void f(T*); 

// ... 

int *p; 
f(p);   // calls (b)! overload resolution ignores 
        // specializations and operates on the base 
        // function templates only 

Hier (c) ist eine explizite Spezialisierung von (a). Warum das? Liegt das an der Bestellung der Deklaration?

+1

Offhand würde ich nur "ja" sagen, und angenommen, der Code ist gültig, das ist die einzig mögliche Antwort. Aber die Frage ist, ob der zweite Code gültig ist. Ich glaube, dass es gültig ist, aber das im Standard zu finden könnte viel Arbeit sein ... –

+0

@Alf P. Steinbach: Warum konnte der zweite Code nicht gültig sein? – Donotalo

+0

@Donato: ignoriere die Autoren (die Really (TM) kennen ihre Sachen, wenn es um Vorlagen geht) Ich bin nur vorsichtig von Code, der Reihenfolge-abhängige oder andere "willkürliche" Wirkung hat. Der Standard soll vor solchen Dingen schützen, nämlich zweistufige Zusammenstellung von Vorlagen schützt vor solchen Dingen. Also ich habe nur ein <0.5% glauben, dass es nur eine Regel gibt, dann möglicherweise eine, die keine Diagnose benötigt. –

Antwort

11

Ja, es liegt an der Reihenfolge der Deklaration. Wenn der Compiler (c) in der zweiten Menge auftritt, ist die einzige zu spezialisierende Vorlage (a).

Deshalb müssen Sie bei der Bestellung Ihrer Vorlagenspezialisierungen vorsichtig sein.

Die Programmiersprache C++ geht ausführlich darauf ein (Abschnitt 13.5.1). Ich empfehle es sehr.

10

Es ist die Bestellung, aber es ist nicht nur die Bestellung. Für den ersten Code wurden beide Vorlagen zuvor definiert. Aber der zweite wurde genommen.

Dies liegt daran, dass die beiden Vorlagen verglichen werden, und es wird festgestellt, dass (T) jede Art übereinstimmt (T*) Matches, aber die (T*) nicht alle Arten übereinstimmt, das (T) Spiele. Daher ist die zweite Vorlage spezialisierter. Immer wenn Sie eine explizite Spezialisierung angeben und diese beiden Vorlagen übereinstimmen, werden die Vorlagen verglichen und der spezialisierter wird durch die explizite Spezialisierung zugeordnet. Dieser Vergleich wird als "partielle Ordnung" bezeichnet.

8

Der Standard muss Folgendes über die relative Positionierung der expliziten Spezialisierungsdeklarationen sagen. [Abschnitt 14.7.3]

Die Platzierung der expliziten Spezialisierung Erklärungen für Funktionsschablonen, Klassenvorlagen, Elementfunktionen von Klassen-Templates, statische Datenelemente von Klassen-Templates, Mitglied Klassen von Klassen-Templates, Mitglied Klassenvorlagen von Klassen-Templates Elementfunktionsvorlagen von Klassenvorlagen, Elementfunktionen von Elementvorlagen von Klassenvorlagen, Elementfunktionen von Elementvorlagen von Nichtvorlagenklassen, Elementfunktionsvorlagen von Elementklassen von Klassenvorlagen usw. und die Platzierung von Teilspezialisierungserklärungen von Klassenvorlagen, Mitgliederklassenvorlagen von Nicht-Vorlagenklassen, Mitgliederklassenvorlagen von Klassenvorlagen usw., kann beeinflussen, ob ein Programm gemäß der relativen Positionierung der expliziten Spezialisierungsdeklarationen und ihrer Instanziierungspunkte in der Übersetzungseinheit wie oben und unter wohlgeformt ist. Wenn Sie eine Spezialisierung schreiben, seien Sie vorsichtig in Bezug auf den Standort. oder um es kompilieren zu lassen, wird so ein Versuch sein, seine Selbstverbrennung anzuzünden.

+1

+1 für ** Selbstverbrennung ** - genug, um Neophyten zu verscheuchen, die C++ lernen wollen – kfmfe04

Verwandte Themen