2011-01-01 12 views
10

Der Titel ist ziemlich selbsterklärend, aber hier ist ein vereinfachtes Beispiel:Können wir eine anonyme Struktur als Vorlage-Argument haben?

#include <cstdio> 

template <typename T> 
struct MyTemplate { 

    T member; 

    void printMemberSize() { 
     printf("%i\n", sizeof(T)); 
    } 

}; 

int main() { 

    MyTemplate<struct { int a; int b; }> t; // <-- compiler doesn't like this 

    t.printMemberSize(); 

    return 0; 

} 

Der Compiler beschwert sich, wenn ich versuche, eine anonyme Struktur als Template-Argument zu verwenden. Was ist der beste Weg, um so etwas zu erreichen, ohne eine separate, benannte Struct-Definition zu haben?

Antwort

7

Sie nicht zu definieren dürfen einen ungenannten Typ als Template-Argument in C++ 03 oder auch in C++ 0x.

Das Beste, was Sie tun können, es eine benannte Struktur lokal für main (in C++ 0x)

1 zu erstellen: Sie sind nicht einen lokalen Typen als Template-Argument in C + zu verwenden, erlaubt +03, aber C++ 0x erlaubt es.

überprüfen Sie auch den Fehlerbericht here. Die vorgeschlagene Lösung erwähnt

Folgende Typen sind nicht als Vorlage-Argument für eine Template-Typ-Parameter verwendet werden:

deren
  • einen Typnamen
  • eine unbenannte Klasse keine Bindung hat oder Aufzählungstyp, der keinen Namen für Verknüpfungszwecke hat (7.1.3 [dcl.typedef])
  • eine cv-qualifizierte Version von einem der Typen in dieser Liste
  • ein durch Anwendung von declarator Betreibern einen der Typen in dieser Liste erstellt Typ
  • eine Funktion Typ, der eine der Verwendungen in dieser Typenliste

Der Compiler beschwert sich, wenn ich versuche, eine anonyme Struktur als Template-Parameter zu verwenden.

Meinten Sie Vorlage Argument? Template-Parameter unterscheidet sich von Template-Argument.

Zum Beispiel

template < typename T > // T is template parameter 
class demo {}; 

int main() 
{ 
    demo <int> x; // int is template argument 
} 
+0

In C++ 0x kann ein Objekt eines unbenannten Typs als Template Argument abgeleitet werden, aber ich denke nicht Ein unbenannter Typ kann explizit in der Vorlagenargumentliste angegeben werden. –

+0

Prasoon, können Sie mich bitte auf den richtigen Teil des Standards verweisen? Mein Testfall mit einer unbenannten Struktur (übergeben an ein typedef, aber wir alle wissen, dass ein typedef Name kein Strukturname ist) kompiliert einfach gut. –

+0

@Ben: '14.3.1/2' –

4

Ihr Problem ist nicht, dass die Struktur unbenannt ist, es ist, dass die Struktur lokal deklariert ist. Lokale Typen als Vorlagenargumente zu verwenden ist in C++ 03 nicht erlaubt. Es wird jedoch in C++ 0x sein, also könnten Sie versuchen, Ihren Compiler zu aktualisieren.

EDIT: Eigentlich Ihr Problem ist, dass die Liste in einer Template-Argumente ist kein juristischer Ort, um eine Klassendefinition zu setzen, mit oder ohne Namen, nach dem C++ Standard.

litb weist darauf hin, dass, obwohl sie paßt in die C++ 0x Grammatik, hier eine Art der Definition von [dcl.type] verboten ist:

Eine Art spezifische er-Seq wird nicht de fi nieren eine Klasse oder Aufzählung, es sei denn es erscheint in der Typ-ID einer Alias-Deklaration (7.1.3), die nicht die Deklaration einer Template-Deklaration ist.

simple-template-id: 
    template-name < template-argument-list_opt > 

template-argument-list: 
    template-argument ..._opt 
    template-argument-list , template-argument ..._opt 

template-argument: 
    constant-expression 
    type-id 
    id-expression 

type-id: 
    type-specifier-seq abstract-declarator_opt 

type-specifier-seq: 
    type-specifier attribute-specifier-seq_opt 
    type-specifier type-specifier-seq 

type-specifier: 
    trailing-type-specifier 
    class-specifier 
    enum-specifier 

class-specifier: 
    class-head { member-specification_opt } 

Eine Zeit lang hatte ich eine Frage über typedef Namen, aber litb gelöscht das wieder wett. Sie werden als Vorlage Argumente über erlaubt:

trailing-type-specifier: 
    simple-type-specifier 
    elaborated-type-specifier 
    typename-specifier 
    cv-qualifier 

simple-type-specifier: 
    :: opt nested-name-specifier_opt type-name 
    :: opt nested-name-specifier template simple-template-id 
    char 
    char16_t 
    char32_t 
    wchar_t 
    bool 
    short 
    int 
    long 
    signed 
    unsigned 
    float 
    double 
    void 
    auto 
    decltype-specifier 

type-name: 
    class-name 
    enum-name 
    typedef-name 
    simple-template-id 
+0

Eigentlich GCC 4.5 der C++ 0x-Funktionen Ich verwende. Ist diese Funktion dort noch nicht implementiert? – nonoitall

+0

@nonoitall: Das [C++ 0x-Tag-Wiki] (http://stackoverflow.com/tags/c%2b%2b0x/info) enthält Links zu vielen Informationen zum Status der C++ 0x-Unterstützung in mehreren Compilern . Es sagt, dass es in gcc 4.5 hinzugefügt werden soll. Die [offiziellen gcc-Versionshinweise] (http://gcc.gnu.org/gcc-4.5/changes.html) sagen "Im C++ 0x-Modus sind jetzt lokale und anonyme Klassen als Vorlagenargumente erlaubt". Sie kompilieren mit der Option "-std = gnu ++ 0x", richtig? –

+0

Mein schlechtes. Offensichtlich ist dies etwas, das im MinGW-Hafen von GCC 4.5 zurückgelassen wurde. Versucht, es auf einer Linux-Box zu kompilieren, und es wird kompiliert, wenn eine lokal definierte Struktur verwendet wird (obwohl die Verwendung einer anonymen Struktur als Argument immer noch nicht möglich ist)./Ich gehe Cygwin installieren. – nonoitall

Verwandte Themen