25 Stimmen

Standard Library Containers mit zusätzlichen optionalen Template-Parametern?

Nachdem ich die Behauptung mehrere Male in Artikeln gelesen habe, möchte ich diese Frage zu Stackoverflow hinzufügen und die Gemeinschaft fragen, ob der folgende Code portabel ist?

template<template<typename T, typename Alloc> class C>
void f() {
  /* some code goes here ... */
}

int main() {
  f<std::vector>();
}

Ist die Implementierung, die die std::vector wirklich zusätzliche, voreingestellte Template-Parameter haben, die über die beiden wohlbekannten hinausgehen? Dies würde den obigen Code unvollständig machen, da er von zwei Vorlagenparametern ausgeht. Siehe den letzten Absatz in diesem Artikel für ein Beispiel einer solchen Forderung.

23voto

Johannes Schaub - litb Punkte 479831

Ich habe Folgendes gefunden Emissionsbericht in der es heißt

Es gibt keine Zweideutigkeit; die Norm ist so klar wie geschrieben. Bibliotheksimplementierer dürfen keine Template-Parameter zu Standardbibliotheksklassen hinzufügen. Dies fällt nicht unter die "als ob"-Regel, so dass es nur dann erlaubt wäre, wenn der Standard den Implementierern eine ausdrückliche Genehmigung dafür erteilen würde. Dies würde eine Änderung der Norm erfordern.

Die LWG entschied sich gegen diese Änderung, da sie den Anwendercode, der Template-Parameter oder Spezialisierungen von Klassen-Templates der Standardbibliothek enthält, zerstören würde.

Die Bücher und Leute, die sagen, dass eine Implementierung andere optionale Parameter hinzufügen kann, scheinen falsch zu sein.

2voto

csj Punkte 20408

Unglaublicherweise las ich kürzlich "C++ Templates: The Complete Guide", und im letzten Buch stand auf Seite 111 folgendes:

Ein Schablonenargument muss eine Klassenschablone mit Parametern sein, die genau mit den Parametern der Schablonenvorlage übereinstimmen, die es ersetzt. Standardvorlagenargumente eines Vorlagenarguments werden ignoriert (wenn der Vorlagenparameter jedoch Standardargumente hat, werden sie bei der Instanziierung der Vorlage berücksichtigt).

Wenn man dem Buch Glauben schenken darf, wäre Ihr Beispiel, in dem nicht standardisierte Standardparameter zu std::vector hinzugefügt werden, legal - da Standardvorlagenargumente einer Vorlagenvorlage ignoriert werden.

Als Praxistest habe ich das Folgende in g++ (erfolgreich) und Visual Studio 2008 (fehlgeschlagen aufgrund der nicht übereinstimmenden Parameter) kompiliert:

template<typename T1, typename T2, typename T3 = float>
class MyClass
{
public:
    T1 v1;
    T2 v2;
    T3 v3;
};

template<template<typename T1, typename T2> class C>
void f()
{
    C<int,double> *c = new C<int,double>();
}

int main ()
{
    f<MyClass>();
    return 0;
}

1voto

me22 Punkte 651

Prüfen Sie die Unterabschnitte von 17.4.4 [lib.conforming].

17.4.4.3/3 besagt, dass "eine globale Funktion oder eine Nicht-Mitgliedsfunktion von der Implementierung nicht mit zusätzlichen Standardargumenten deklariert werden kann", aber 17.4.4.4/2 erlaubt ausdrücklich das Ersetzen der beschriebenen Signaturen von Mitgliedsfunktionen durch längere, solange die zusätzlichen Parameter Standardwerte haben.

Es gibt jedoch keinen Abschnitt für Vorlagen. Wenn sie also das Bedürfnis hatten, 17.4.4.3/3 zu erstellen, scheint es mir, dass zusätzliche Vorlagenparameter zulässig sind, sofern kein gegenteiliger Wortlaut vorliegt.

0voto

sbi Punkte 211669

Ich habe diese Behauptung auch schon gesehen. Aber.

Zum einen habe ich noch nie eine Implementierung gesehen, die dies tut. Ich glaube mich zu erinnern, dass Andrei Alexandrescu einmal darüber nachgedacht hat, so etwas wie Allokator-Typen auf Steroiden zu verwenden (etwas wie my_fancy_thing<std::allocator,more_info_to_pass_to_the_container> , während nur std::allocator würde auch noch funktionieren). Aber auch dann bliebe Ihr f() funktioniert, und das ist das, was einer Umsetzung Ihres Beispiels am nächsten kommt, von dem ich je gehört habe, dass es diskutiert wird.

Ich denke, dies fällt ziemlich genau in die gleiche Kategorie wie die Behauptung, dass ein 0 Zeiger muss nicht unbedingt durch einen Wert dargestellt werden, bei dem alle Bits auf Null gesetzt sind - selbst wenn die Anbieter diese Freiheit wirklich haben (was ich nicht weiß, da es auch Behauptungen von beiden Seiten gibt), werden sie sie nie nutzen, da dies praktisch den gesamten bestehenden Code zerstören würde.

Deshalb habe ich schon lange beschlossen, mir darüber keine Gedanken mehr zu machen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X