【问题标题】:Template template parameter simple example模板模板参数简单示例
【发布时间】:2017-08-24 22:17:44
【问题描述】:

首先我在学习模板模板参数,我开始想知道我是否有一个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

【问题讨论】:

  • 试试 vector::value_type - 无需复杂化。

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


【解决方案1】:

您缺少的是 vector 具有多个模板参数(其中大多数具有默认值)。 您需要为此准备函数

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

注意class后面的点

【讨论】:

    【解决方案2】:

    +1 表示 Bartosz Przybylski 的回答,这解释了为什么您的示例无法编译,但您想要

    从那里提取类型 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, "!" );
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-14
      • 1970-01-01
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 2011-06-13
      相关资源
      最近更新 更多