【问题标题】:How to detect C-style multidimensional arrays in templates specialization?如何在模板专业化中检测 C 风格的多维数组?
【发布时间】:2022-01-07 19:53:23
【问题描述】:

我有以下代码:

enum type_kind{unkown=-1,carray, multi_carray};

template<class T>
struct detect_carray{
   constexpr static int kind=unkown;
};
template<class T, std::size_t N>
struct detect_carray<T[N]>{
   constexpr static int kind=carray;
};

现在,我想添加另一个专门用于检测 C 风格的多维数组,即T[a][b]...

实现这一点的语法是什么?我可以使用可变参数模板吗?

我期望以下行为:

int main()
{
std::cout<<detect_carray<std::vector<int>>::kind;//-1
std::cout<<detect_carray<int[3]>::kind;//0
std::cout<<detect_carray<double[3][5]>::kind;//1
std::cout<<detect_carray<std::complex<double>[3][5][8][16]>::kind;//1
//Correct out: -1011
}

【问题讨论】:

    标签: c++ templates c++17 c++20


    【解决方案1】:

    标准库中已经有一个名为std::rank 的特征,因此解决方案非常简单:

    template <class T>
    struct detect_carray {
      enum type_kind { unknown = -1, carray, multi_carray };
    
      static constexpr int kind = [] {
        switch (std::rank_v<T>) {
          case 0: return unknown;
          case 1: return carray;
          default: return multi_carray;
        }
      }();
    };
    

    【讨论】:

      【解决方案2】:

      只需为多维数组添加一个特化:

      template<class T, std::size_t N1, std::size_t N2>
      struct detect_carray<T[N1][N2]>{
         constexpr static int kind=multi_carray;
      };
      

      然后

      std::cout<<detect_carray<std::vector<int>>::kind;//-1
      std::cout<<detect_carray<int[3]>::kind;//0
      std::cout<<detect_carray<double[3][5]>::kind;//1
      std::cout<<detect_carray<std::complex<double>[3][5][8][16]>::kind;//1
      

      LIVE

      顺便说一句:对于double[3][5]T 将是 double(而 N1 将是 3N2 将是 5)。对于std::complex&lt;double&gt;[3][5][8][16]T 将为std::complex&lt;double&gt; [8][16]N1 将为3N2 将为5)。

      【讨论】:

        猜你喜欢
        • 2020-07-18
        • 1970-01-01
        • 2017-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-27
        • 1970-01-01
        • 2015-08-01
        相关资源
        最近更新 更多