2015-06-16 10 views
6

Z praktycznego punktu widzenia, rozumiem, że zarówno typedef i test są nieco „zbędny” i muszą zostać usunięte, jeśli chcemy następujący kod do kompilacji:Dlaczego szablony typedef są nielegalne?

template< typename type_t > 
typedef struct tagTest 
{ 
    int a; 
} test; 

Jednak myślałem, że zbiór Deklaracje typedef stanowiły podzbiór zbioru deklaracji. Po prostu przydarzyło się, że mają specyficzny specyfikator dekodowania . To była moja racjonalizacja dla

typedef struct tagTest 
{ 
    int a; 
} test; 

wprowadzającej identyfikator testi deklarując strukturę tagTest. Jeśli ta interpretacja jest poprawna, to następujący akapit ze standardu powinien pozwolić na templatetypedef (chociaż nie ze znaczeniem podanym przez słowo kluczowe using).

Oświadczenie w szablonie-zgłoszeniu są - (1,1) stwierdzenie czy zdefiniowania funkcji, klasę lub zmienna lub - (1.2) określić funkcję członu klasa człon , a wyliczenie element lub statyczny element danych z klasy matrycy lub klasy zagnieżdżone w szablonie klasy lub - (1,3) określenie szablonu do klasy lub klasy szablonu lub - (1,4) być deklaracją aliasową.

Nie widzę błędu w moim uzasadnieniu, ale wniosek jest nielegalny.

Jakie są odpowiednie części normy, które rozwiązują powyższą zagadkę?


UPDATE Część powyższego rozumowania wykorzystuje fakt, że typedefstruct deklaruje strukturę. Specyfikator typedef, o ile rozumiem, oznacza, że ​​zadeklarowane zmienne są naprawdę typami. Oznacza to, że typedef aktualizuje się z samej zmiennej do typu, który jest równoważny z deklarowanym tagTest. Dlatego poniższy kod kompiluje (aczkolwiek z ostrzeżeniem).

typedef struct tagTest 
{ 
    int a; 
}; 
tagTest t; 

Jedna z odpowiedzi zajmuje się zbędnym test.Ale możliwe jest użycie typedef bez declarator because „Init-declarator-lista jest opcjonalny podczas deklarowania nazwanego klasa/struct/Unii lub nazwie wyliczanie”

+0

Er ... Żaden z tych przypadków go nie obejmuje. Fakt, że deklaracja zawiera coś, co deklaruje klasę, nie oznacza, że ​​deklaracja sama deklaruje klasę. Deklaracja ogranicza się do zdefiniowania rodzaju. – hvd

+0

@ hvd W języku C, typedef zawierający znakowaną strukturę deklaruje tę strukturę, a także definiuje nazwę, która ją modyfikuje. Czy mówisz, że C++ jest inny pod tym względem? – davmac

+0

@davmac Nie, zgadzamy się co do końcowego efektu takiej deklaracji. Twierdzę, że częścią, która powoduje, że struktura jest deklarowana, nie jest sama deklaracja, tylko podskładnik tej deklaracji. Dotyczy to zarówno C jak i C++. – hvd

Odpowiedz

3

Template typedefs nie pozwolono wstępnie C++ 11 i C++ 11 template aliases zostały wprowadzone do rozwiązania te problemy. Cfr. C++ template typedefs i wikipedia.

Ponieważ, jak już wspomniano, norma nie pozwala typedef się tam, że kod jest nieprawidłowy

alias-deklaracja:

using identifier attribute-specifier-seqopt= type-id ; 

typedef deklaracje nie są alias deklaracje.

Ponadto nie można mieć declarator jeśli deklarując szablonu klasy, jest wyraźnie zabronione przez standardową

[temp]/P3

w szablonie-deklaracji jawna specjalizacja lub jawna inicjacja listy deklaratorów init w deklaracji zawierają co najwyżej jeden deklarator. Gdy taka deklaracja jest używana do deklarowania szablonu klasy, nie jest dozwolony żaden deklarator.

więc nawet nie dodaje się skompiluje

template< typename type_t > 
struct tagTest 
{ 
    int a; 
} test; 

Edit:

To jest nigdzie określone, że

typedef struct S { }; 

powinien być błąd, a zatem zarówno gcc i clang zaakceptuj to ostrzeżeniem. Zakładam Clang liczy na [temp]/3 wydać błąd w przypadku typedef był używany z szablonem podczas gcc odrzuca ten kod natychmiast

template<typename T> 
typedef struct S { }; 

CFR. clang bug 22249

+0

Usunięcie tokena 'test', ale zachowanie specyfikatora' typedef' powinno być legalne, ponieważ deklaratory są opcjonalne. – Hector

+0

@Hector edytował pytanie, aby dodać szczegóły dotyczące tej sprawy. –

+0

+1 Ten link o clang jest miły. Ale jeśli chodzi o twój pierwszy akapit, nie twierdzę, że 'szablon typedef struct S {};' powinien działać w taki sam sposób jak słowo kluczowe 'using'. Twierdzę, że standard pozwala na to, aby był legalny z tym samym znaczeniem co 'template struct S {};'. – Hector

1

Niezależnie od tego, co typedef określi, że jest to deklaracja typedef , które nie są wymienione w tych przypadkach:

  • [element] funkcja
  • [element] Klasa
  • zmienna
  • elementu wyliczenia
  • statyczne członek danych klasy szablonu/z klasy zagnieżdżone wewnątrz szablonu klasy
  • członek szablonu klasy lub klasy szablonu
  • deklaracja alias

I żeby była jasność typedef deklaracje nie są alias deklaracje. deklaracja Alias ​​, w sposób określony przez gramatyki w §7 standardu to:

alias-deklaracja:

using identifier attribute-specifier-seqopt= type-id ;

Nie wspominając, że gdyby to było możliwe, następnie deklaracja szablonu nie będzie już tak "cool", jak dzisiaj, i there would be little to no sense to have both.

+0

Myślę, że punktem OP jest to, że tekst nie _powinien powiedzieć, że deklaracja musi być "deklaracją klasy" [członka] "(pośród innych typów), ale raczej że" deklaruje lub definiuje "klasę, którą typedef z struct pod-deklaracja prawdopodobnie to robi. – davmac

1

C nie obsługuje szablonów i składnia w C++

typedef struct tagX { 
} X; 

jest szczątkowa C, tam, aby umożliwić dalsze wsparcie dla C nagłówków itp, nie do zastosowania w rzeczywistych C++.

C++ składni powyżej jest

struct X {}; 

(YMMV na umieszczenie obejmy)

Powiązane problemy