2011-01-01 11 views
10

Tytuł jest dość oczywiste, ale tu jest uproszczony przykład:Czy możemy mieć anonimową strukturę jako argument szablonu?

#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; 

} 

Kompilator narzeka gdy próbuję użyć anonimowego struct jako szablonu argumentu. Jaki jest najlepszy sposób na osiągnięcie czegoś takiego bez konieczności posiadania oddzielnej, nazwanej definicji struktury?

Odpowiedz

7

Nie wolno określić nienazwany typ jako argument szablonu w C++ 03 lub nawet w C++ 0x.

Najlepiej można to zrobić aby utworzyć nazwany struct lokalnego do main (w C++ 0x)

1: Nie wolno używać lokalnego typu jako szablon argumentu w C + +03, jednak pozwala na to C++ 0x.

Sprawdź również raport o defekcie here. Proponowane rozwiązanie wspomina

następujące rodzaje nie mogą być stosowane jako szablon-argumentem dla szablonu typu parametru:

  • typu, którego nazwa ma powiązania
  • nienazwany klasy lub typ wyliczeniowy, który nie ma nazwy dla celów powiązań (7.1.3 [dcl.typedef])
  • CV wykwalifikowanych wersja jednego z typów na tej liście
  • typu tworzone przez zastosowanie operatorów declarator do jednego z typów na tej liście
  • typu funkcja, która wykorzystuje jedną z typy na tej liście

kompilator narzeka gdy próbuję użyć anonimowego struct jako parametr szablonu.

Czy chodziło Ci o szablon? Parametr szablonu różni się od argumentu szablonu.

Na przykład

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

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

W C++ 0x, obiekt typu nienazwanego można wyprowadzić jako argument szablonu, ale nie sądzę Typ bez nazwy może być określony jawnie na liście argumentów szablonu. –

+0

Prasoon, czy możesz skierować mnie do właściwej części normy? Mój przypadek testowy z nienazwaną strukturą (przekazywany do typedef, ale wszyscy wiemy, że nazwa typedef nie jest nazwą struktury) kompiluje się dobrze. –

+0

@Ben: '14.3.1/2' –

4

Twój problem nie polega na tym, że nazwa struktury jest bez nazwy, ponieważ struktura jest zadeklarowana lokalnie. Używanie lokalnych typów jako argumentów w szablonach jest niedozwolone w C++ 03. Będzie jednak w C++ 0x, więc możesz spróbować uaktualnić swój kompilator.

EDYCJA: W rzeczywistości twój problem polega na tym, że wewnątrz listy szablonów nie jest legalne miejsce do umieszczenia definicji klasy, z lub bez nazwy, zgodnie ze standardem C++.

litb zwraca uwagę, że chociaż pasuje do gramatyki C++ 0x, określające typ tutaj jest zabronione przez [dcl.type]: Typ-specy fi er-nast powinien chyba że pojawi się klasa lub wyliczenie

nie de fi ne w identyfikatorze typu deklaracji (7.1.3), która nie jest deklaracją szablonu.

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 } 

Przez chwilę miałem pytanie o typedef nazwisk, ale litb wyczyszczone, że aż. Są one dopuszczone jako argumenty szablonu poprzez:

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

Właściwie używam GCC 4.5 w C++ 0x możliwości. Czy ta funkcja nie jest jeszcze dostępna? – nonoitall

+0

@nonoitall: [tag wiki C++ 0x] (http://stackoverflow.com/tags/c%2b%2b0x/info) zawiera łącza do wielu informacji o stanie obsługi C++ 0x w kilku kompilatorach . Mówi się, że powinno być dodane w gcc 4.5. [Oficjalne uwagi do wydania gcc] (http://gcc.gnu.org/gcc-4.5/changes.html) mówią: "W C++ 0x, lokalne i anonimowe klasy są teraz dozwolone jako argumenty szablonów". Kompilujesz z opcją '-std = gnu ++ 0x', prawda? –

+0

Mój zły. Najwyraźniej jest to coś, co zostało pozostawione na porcie MinGW w GCC 4.5. Próbowałem skompilować go na Linuksie i skompiluje się przy użyciu lokalnie zdefiniowanej struktury (chociaż użycie anonimowej struktury jako argumentu nadal nie będzie latać)./mnie idzie do instalacji Cygwin. – nonoitall

Powiązane problemy