Ich verstehe, dass der Nicht-Typ-Vorlagenparameter ein konstanter integraler Ausdruck sein sollte. Kann jemand Licht ins Dunkel bringen, warum es so ist?
template <std::string temp>
void foo()
{
// ...
}
error C2993: 'std::string' : illegal type for non-type template parameter 'temp'.
Ich verstehe, was ein konstanter integraler Ausdruck ist. Was sind die Gründe dafür, dass nicht konstante Typen wie std::string
im obigen Snippet nicht zugelassen werden?
Antworten:
Der Grund, warum Sie dies nicht tun können, ist, dass nicht konstante Ausdrücke während der Kompilierungszeit nicht analysiert und ersetzt werden können. Sie können sich zur Laufzeit ändern, was die Generierung einer neuen Vorlage zur Laufzeit erforderlich machen würde. Dies ist nicht möglich, da Vorlagen ein Konzept zur Kompilierungszeit sind.
Folgendes erlaubt der Standard für nicht typisierte Vorlagenparameter (14.1 [temp.param] p4):
quelle
Das ist nicht erlaubt.
Dies ist jedoch zulässig:
Siehe §14.1 / 6,7,8 in C ++ Standard (2003).
Illustration:
Ausgabe:
quelle
std::string
Zeigers oder Referenzobjekts ist. Wenn diese Variable lokal wäre, würden Sie möglicherweise bei jedem Aufruf der Funktion unterschiedliche Adressen erhalten.Sie müssen in der Lage sein, Vorlagenargumente zu entstellen
Jetzt müsste ein Impl eine eindeutige Folge von Zeichen für eine
std::string
oder für jede andere beliebige benutzerdefinierte Klasse erstellen, die einen bestimmten Wert speichert, dessen Bedeutung der Implementierung nicht bekannt ist. Außerdem kann der Wert beliebiger Klassenobjekte zur Kompilierungszeit nicht berechnet werden.Es ist geplant, Literalklassentypen als Vorlagenparametertypen für Post-C ++ 0x zuzulassen, die durch konstante Ausdrücke initialisiert werden. Diese können entstellt werden, indem die Datenelemente gemäß ihren Werten rekursiv entstellt werden (für Basisklassen können wir beispielsweise die Tiefenüberquerung von links nach rechts anwenden). Aber es wird definitiv nicht für beliebige Klassen funktionieren.
quelle
Ein nicht typisiertes Vorlagenargument, das in einer Vorlagenargumentliste bereitgestellt wird, ist ein Ausdruck, dessen Wert zur Kompilierungszeit bestimmt werden kann. Solche Argumente müssen sein:
String-Literale sind auch Objekte mit interner Verknüpfung, sodass Sie sie nicht als Vorlagenargumente verwenden können. Sie können auch keinen globalen Zeiger verwenden. Gleitkomma-Literale sind aufgrund der offensichtlichen Möglichkeit von Rundungsfehlern nicht zulässig.
quelle