2013-09-25 18 views
9

Mój problem może być wznowione przez następujący fragment kodu:argumentem

template <typename T> struct C2; 

template <typename T> 
struct C1 
{ 
    template <typename Type, 
     template <typename Ti> class Container = C2> 
    void m() {} 
}; 


template <typename T> 
struct C2 
{ 
    template <typename Type = int, 
     template <typename Ti> class Container = C2> // <-- Here is the problem! 
    void m() {} 

}; 

kompilatora GNU w wersji 4.8.1 nie powiedzie się z następującym komunikatem:

test-temp.C:16:47: error: invalid use of type ‘C2<T>’ as a default value for a template template-parameter 
     template <typename Ti> class Container = C2> 

It odnosi się do domyślnego parametru szablonu C2 dla metody C2 :: m.

Najwyraźniej (moim zdaniem), kompilator widzi C2<T> jako domyślny parametr zamiast C2 (bez <T>). Tak więc, gdy znajdzie instrukcję, nie powiedzie się, ponieważ typ C2<T> nie pasuje do Container.

Klang ++, dla dokładnie tego samego kodu, kompiluje się dobrze!

Moje pytania:

  1. Który kompilator ma prawdy?
  2. Czy jest jakaś alternatywa dla wyrażenia tego samego sensu z bieżącą wersją kompilatora gnu?

góry dzięki

Leandro

+0

g ++ jest niepoprawny, clang jest poprawny, również nazwa w szablonie szablonu jest opcjonalna – aaronman

Odpowiedz

9

myślę Clang jest prawidłowa, oraz g ++ jest w błędzie, cytat z projektu normy (pogrubienie podkreślenie moje)

14.6.1 Lokalnie deklarowane nazwy [tymczasowe]

1 Podobnie jak w przypadku normalnych (nie szablonowych) klas, szablonów klas mieć nazwę klasy wstrzykniętej (Klauzula 9). Nazwa injectedclass może być używana jako nazwa szablonu lub nazwa typu. Gdy jest używany z szablonem-argumentu liście , jako szablon-argumentem za szablon szablonach parametru, lub jako wersja ostateczna identy fi er w opracowana-typespeci fi er deklaracji przyjaciel klasy szablonu, to dotyczy sam szablon klasy. W przeciwnym razie jest to równoważne z nazwą-szablonem, a następnie szablonowymi parametrami szablonu klasy zawartymi w <>.

Można użyć operatora rozdzielczości :: zakres pokonać g ++ do składania

template <typename T> 
struct C2 
{ 
    template <typename Type = int, 
     template <typename Ti> class Container = ::C2> 
               // ^^ <-- here is the solution! 
    void m() {} 

}; 

Live Example.

+0

Genialny! ... i na czas. Dzięki! – lrleon

+0

@Ilele cieszę się, że mogłem pomóc. Witamy w Stackoverflow! – TemplateRex

+1

@TemplateRex Mam nadzieję, że albo Irleon, albo sprawdzisz, czy GCC ma raport o błędzie dla tego czy utworzonego? SO jest ładne, ale nie naprawia rzeczy. Zazwyczaj linkuję do bugzilli, aby dać znać ludziom, aby mogli później sprawdzić, dla której wersji problem został naprawiony. (też: +1) –

0

Podobnie odniesienie 14.6.1 w odpowiedzi TemplateRexa oznacza, że ​​G ++ jest poprawne (i Clang i VC++ są nieprawidłowe), aby to zaakceptować, ponieważ używa X jako argumentu szablonu dla parametru szablonu szablonu?

template< template<typename> class T > 
class factory { }; 

template< typename T > 
class X 
{ 
     friend class factory<X>; // *** 
}; 

int main() 
{ 
} 

W tym przykładzie X g ++ traktuje jako nazwa szablonu klasy, natomiast Clang i VC++ traktować go jako wtryskiwanego nazwą klasy.

Powiązane problemy