2017-07-21 1 views
-2

Ich lerne Lambda-Ausdruck in C++ 11x, ich googelte für die gleiche und stolperte unter Code-Snippet, wo Vorlage Typname als eine Vererbung verwendet.Verwendung der Vorlage in der Struktur in C++

Sprich

template< class T > 
    struct MyType : T { 
      .... 

Wenn ich den Code erfüllt es keine Störungen nicht geben. Aber als ich versuchte, eine Instanz für die Struktur MyType zu erstellen, führte dies zu einem Fehler.

// Example program 
#include <iostream> 
#include <string> 

template< class T > 
struct MyType : T { 
    static const auto data = 0; 
    static const size_t erm = sizeof(data); 
}; 


int main() 
{ 
    struct MyType<int> my; 
    std::cout<<"\n test "; 
    return 0; 
} 

Fehler bei dem oben genannten Code kompiliert:

In instantiation of 'struct MyType<int>': 
    15:22: required from here  
    6:8: error: base type 'int' fails to be a struct or class type In function 'int main()': 
    15:22: warning: unused variable 'my' [-Wunused-variable] 

Bitte etwas Licht auf dem gleichen hinzuzufügen. Warum Kompilierung gibt Fehler beim Instanziieren der Struktur? Auf der anderen Seite Warum Erklärung gibt keinen Fehler?

Vielen Dank im Voraus.

+4

Der Typparameter wird als Basisklasse für Ihren Typ verwendet. 'int' ist keine Klasse und Sie können nicht von ihr erben. Sie benötigen eine andere Struktur (oder Klasse) als Basis. Ich denke, die Fehlermeldung message _base Typ 'int' ist keine Struktur oder Klasse_ ist ziemlich klar ... – Useless

Antwort

3

Ich denke, der Compiler gibt eine ziemlich gute Erklärung. Kurz gesagt, Sie können nicht von grundlegenden Typen wie int ableiten.

Die Erklärung selbst:

template< class T > 
struct MyType : T { 
    static const auto data = 0; 
    static const size_t erm = sizeof(data); 
}; 

ist absolut gültig. Also beschwert sich der Compiler nicht darüber.

Aber wenn es um Instanziierung MyType<T> mit T = int kommt der Compiler versucht, den Code zu erzeugen, die, allgemein gesprochen, sieht wie folgt aus:

struct MyType : int { 
    static const auto data = 0; 
    static const size_t erm = sizeof(data); 
}; 

, die nicht gültig C++ weil MyType versucht aus zu erben ist int.

0
  • Das Problem ist, dass T mit dem tatsächlichen Typ ersetzen Sie struct MyType<int> my; wurde vergangen war:

    struct MyType : int

können Sie sehen, warum dies nicht gültig ist. Sie können nicht von etwas erben, das keine Klasse ist. int ist ein einfacher eingebauter Typ.

Es gibt eine Reihe von Grunde, warum dies nicht möglich ist, aber in meiner Meinung alle auf die Tatsache eingehen, dass Vererbung, Polymorphismus und Verkapselung nicht zu Einbau-Grundtypen gilt. Sie haben keine Methodentabelle, daher können Sie sie nicht überschreiben ...

Der Compiler gibt Ihnen bereits eine gute Nachricht Fehler:

clang++ ist wahrscheinlich klarer sagen

test.cpp:9:17: error: base specifier must name a class 
struct MyType : T { 

während icpc

test.cpp(9): error: not a class or struct name 
    struct MyType : T 
4

Warum Kompilation gibt Fehler auf die Struktur der Instanziierung? auf der anderen Seite Hand Warum Erklärung gibt keinen Fehler?

Das ist, weil genaugenommen eine Vorlage Deklaration nicht Code ist. Nur wenn Sie es mit konkreten Vorlagenparametern instanziieren, wandelt der Compiler die Vorlage in "echten" Code um. Sie erhalten keinen Fehler bei der Template-Deklaration, da für jede Struktur oder Klassenart Ihre Vorlage in Ordnung ist. Nur wenn eine Vorlage für einen Template-Parameter schlecht formatiert ist, wird sich der Compiler beschweren, bevor Sie ihn instanziieren. Z.B. dies

template <typename T> 
void foo() { asdf(); } 

wird zu einem Fehler führen (sofern keine asdf im Gültigkeitsbereich befindet):

prog.cpp: In function ‘void foo()’: 
prog.cpp:5:20: error: there are no arguments to ‘asdf’ that depend on a 
template parameter, so a declaration of ‘asdf’ must be available  
[-fpermissive] void foo() { asdf(); } 

aber dies

template <typename T> 
void foo() { T::asdf(); } 

nicht, denn es kann ein T sein, dass wird dazu führen, dass die Vorlage wohlgeformt ist. Nur wenn Sie es mit einer T instanziieren, die keine T::asdf() hat, erhalten Sie eine Fehlermeldung.

Verwandte Themen