2017-08-24 15 views
0

Zuerst lernte ich über Template-Template-Parameter, und ich begann zu fragen, ob ich eine vector<vector<int>> hätte, wenn ich eine Vorlage machen könnte, die den Typ int von dort extrahiert.Template Vorlage Parameter einfaches Beispiel

Aber in dem Prozess zu versuchen, ein Beispiel zu bauen, kann ich nicht einmal eine einstufige Vorlage Parameter Vorlage Funktion zu arbeiten!

#include <iostream> 
#include <vector> 

template< 
    template<class> class C2, 
    class I 
> 
void for_2d(const C2<I>& container) 
{ 
    for(auto j : container){ 
     std::cout << j; 
    } 
} 

int main() { 
    std::vector<int> cont; 
    for_2d(cont); 
    return 0; 
} 

Dies erzeugt:

17 : <source>:17:5: error: no matching function for call to 'for_2d' 
    for_2d(cont); 
    ^~~~~~ 
8 : <source>:8:6: note: candidate template ignored: substitution failure : template template argument has different template parameters than its corresponding template template parameter 
void for_2d(const C2<I>& container) 
    ^
1 error generated. 
Compiler exited with result code 1 
+0

Try vector :: value_type -kein brauchen es zu erschweren. – erenon

Antwort

6

Das, was Sie fehlt, ist, dass Vektor mehrere Vorlagen Argumente hat (die meisten von ihnen hat einen Wert default). Sie benötigen eine Funktion für dieses

template< 
    template<class...> class C2, 
    class I 
> 
void for_2d(const C2<I>& container) 
{ 
    for(auto j : container){ 
     std::cout << j; 
    } 
} 

Hinweis die Punkte nach class

0

+1 für die Bartosz Przybylski Antwort vorzubereiten, die erklären, warum Ihr Beispiel nicht kompilieren, aber Sie wollen

Extrakte aus dem Typ int von dort

Sie auto j : container verwenden, so Du benutzt (mindestens) C++ 11; also schlage ich Ihnen die Implementierung einer spezifischen und rekursiven Typeigenschaft vor.

Ich schlage vor, die folgende firtType Vor allem die generische (nicht spezialisierte) Version (das ist die Rekursion Terminal)

template <typename T> 
struct firstType 
{ using type = T; }; 

Als nächstes wird die Spezialisierung für std::vector und andere Behälter ähnlichen Behälter (das eine seguence Aufnahme von Typen)

template <template <typename...> class C, typename T0, typename ... Ts> 
struct firstType<C<T0, Ts...>> 
{ using type = typename firstType<T0>::type; }; 

arbeitet Diese Spezialisierung mit vielen Containern, aber nicht mit std::array, die einen Typ und eine Nummer erhalten; Folgendes ist eine Spezialisierung für std::array

template <template <typename, std::size_t> class C, typename T, std::size_t N> 
struct firstType<C<T, N>> 
{ using type = typename firstType<T>::type; }; 

Weitere Spezialisierungen erforderlich.

Das folgende ist ein voll funktionierendes Beispiel

#include <array> 
#include <vector> 
#include <type_traits> 

template <typename T> 
struct firstType 
{ using type = T; }; 

template <template <typename...> class C, typename T0, typename ... Ts> 
struct firstType<C<T0, Ts...>> 
{ using type = typename firstType<T0>::type; }; 

template <template <typename, std::size_t> class C, typename T, std::size_t N> 
struct firstType<C<T, N>> 
{ using type = typename firstType<T>::type; }; 

int main() 
{ 
    std::vector<int>     vi; 
    std::array<long, 42U>   al; 
    std::vector<std::vector<short>> vvs; 

    static_assert(std::is_same<typename firstType<decltype(vi)>::type, 
           int>::value, "!"); 
    static_assert(std::is_same<typename firstType<decltype(al)>::type, 
           long>::value, "!"); 
    static_assert(std::is_same<typename firstType<decltype(vvs)>::type, 
           short>::value, "!"); 
} 
Verwandte Themen