模板模板参数简单示例

时间:2017-08-24 22:17:45

标签: c++ c++11 templates typetraits template-templates

首先,我正在学习模板模板参数,我开始想知道我是否有vector<vector<int>>,如果我可以制作一个从那里提取出类型int的模板。

但是,在尝试构建示例的过程中,我甚至无法使用单级模板参数模板函数来工作!

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

这会产生:

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

2 个答案:

答案 0 :(得分:6)

你缺少的是vector有多个模板参数(大多数都有默认值)。 你需要为这个

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

注意class

之后的点

答案 1 :(得分:0)

为Bartosz Przybylski的答案+1,这解释了为什么你的例子没有编译,但你想要

  

从那里提取出类型int

您使用auto j : container,因此您正在使用(至少)C ++ 11;所以我建议你实现一个特定的,递归的类型特征。

我建议以下firtType 首先,通用(非专用)版本(即递归终端)

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

接下来std::vector和其他容器类似容器的特化(接收类型的序列)

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

此专业化适用于许多容器,但不适用于std::array,它们接收类型和数字;以下是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; };

可能需要其他专业。

以下是一个完整的工作示例

#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, "!" );
 }