2011-12-15 6 views
9

Używam gcc 4.4 w przypadku wyciskania Debiana. Rozważ następujący kod.Parametry szablonu szablonów i szablony variadyczne z gcc 4.4

#include <map> 
#include <string> 
using std::map; 
using std::string; 

// Args lets the user specify additional explicit template arguments 
template <typename T, 
     template <typename T, typename... Args> class C, 
     typename... Args> 
C<T, Args...> foo() 
{ 
    C<T, Args...> x; 
    return x; 
} 

int main(void) 
{ 
    map<string, int> a = foo<string, map, int>(); 
} 

Więc idea jest taka, że ​​T mecze string, C tenis map i szablonu parametr opakowań Args mecze int. Być może część składni jest błędna, proszę poprawić. W szczególności, jeśli chcemy, aby pierwszy argument szablonu w class C pasował do , a reszta, aby pasowała do pakietu parametrów szablonu Args, to czy poprawna składnia jest równa template <typename T, typename... Args> class C?

To daje błąd

In function 'int main()': 
post.cc:18: error: no matching function for call to 'foo()' 

To wydaje się być podobna do pytania Variadic template templates and perfect forwarding. To pytanie sugeruje, że jest to błąd gcc, ale może się mylę, myśląc, że te pytania są o tym samym.

Prosimy o zachowanie delikatności. Moja wiedza na temat szablonów variadycznych jest krótsza niż 12 godzin; Próbowałem po prostu przepisać jakiś stary kod C++, aby ograniczyć duplikowanie. Minęło trochę czasu, odkąd zrobiłem C++. Jeśli istnieje obejście problemu, proszę dać mi znać. Dzięki.

EDYCJA: Obejście zaproponowane w komentarzach Variadic template templates and perfect forwarding przez Ise Wisteria zadziałało dla mnie, co sugeruje, że jest to ten sam błąd. Oczywiście, jestem teraz (a) zastanawia się, jak kruche jest to obejście i (b) dlaczego to działa, i co zmotywowało Ise do myślenia o tym. Chociaż sądzę, że tylko Ise może odpowiedzieć na ostatnią chwilę. :-)

+0

Kod kompiluje się na g ++ 4.7. Powinien być błędem. – kennytm

+0

@KennyTM: Dzięki. To znaczy, że nie muszę tego zgłaszać, prawda? –

+0

W prawo. ~~~~~~~~~ – kennytm

Odpowiedz

3

Jak omówiono w edycji moje pytanie wydaje się łaskotać ten sam błąd jak połączonego pytanie Variadic template templates and perfect forwarding. W szczególności obejście tam podane w łączu działa również w moim przypadku. Zmodyfikowany kod, który działa, jest następujący:

#include <map> 
#include <string> 
using std::map; 
using std::string; 

template <typename T, 
     template <typename T, typename... Args> class C, 
     typename... Args> 
struct X 
{ 
    typedef C<T, Args...> type; 
}; 

template <typename T, 
     template <typename T, typename... Args> class C, 
     typename... Args> 
typename X<T, C, Args...>::type foo() 
{ 
    C<T, Args...> x; 
    return x; 
} 

int main(void) 
{ 
    map<string, int> a = foo<string, map, int>(); 
} 
0

Nie sądzę, aby parametry szablonu variadic mogły pasować do argumentów innych niż variadyczne w g ++ 4.4, więc musisz przeładować funkcję foo na wersję nie-variadyczną.

Należy również pamiętać, że mapa rzeczywiście ma więcej niż dwa parametry szablonu i dlatego nie będzie pasować do nowej funkcji foo.

Ten dodatek do przykładu powinno to wyjaśnić:

#include <map> 
#include <string> 
using std::map; 
using std::string; 

// Args lets the user specify additional explicit template arguments 
template <typename T, 
      template <typename T, typename... Args> class C, 
      typename... Args> 
C<T, Args...> foo() { 
    C<T, Args...> x; 
    return x; 
} 

template<typename T, template<typename, typename> class C, typename Arg> 
C<T, Arg> foo() { 
    return C<T, Arg>(); 
} 

template<typename T, typename... Args> class A {}; 

template<typename T, typename Arg> class B {}; 

int main(void) { 
    map<string, int> a = foo<string, map, int>(); // fails. 
    A<string, int> x = foo<string, A, int>(); 
    B<string, int> y = foo<string, B, int>(); 
} 
+0

Nie, szablony variadic są wyraźnie w stanie dopasować nievariadyczne szablony. – Xeo

+0

@Xeo: Nie na g ++ 4,4 – masaers

+0

Cóż, to błąd. Mówię o tym, co mówi standard."Nie sądzę, aby parametry szablonu wariasu mogły pasować do argumentów innych niż wariacyjne" zdawało się sugerować, że tak właśnie jest w ogóle. – Xeo