可以采用不同尺寸的数组的函数

时间:2018-06-07 13:58:56

标签: c++ multidimensional-array vector

是否有一种创建单个函数的方法可以在不重载的情况下获取向量的任何维度?

目前我有,

someFunction(vector<int> a)
someFunction(vector<vector<int> > a)
someFunction(vector<vector<vector<int> > > a)

但是,是否可以有一个功能:

singleFunction(<n-dimension vector>)
{
    // Get dimension of array/vector
}

5 个答案:

答案 0 :(得分:4)

您可以使用递归模板函数

#include <iostream>
#include <vector>

void func(int el) {
  std::cout << el << std::endl;
}

template<typename T>
void func(std::vector<T> v) {
  for (const T& el : v) {
    func(el);
  }
}

int main() {
  std::vector<std::vector<int>> v {{1, 2}, {2, 3}};
  func(v);
  return 0;
}

它为每个元素调用它本身,直到它到达int类型的元素。

要获得尺寸,您可以使用相同的模式:

#include <iostream>
#include <vector>

template<typename T>
int someFunction(std::vector<T> v, int dim = 1);

template<>
int someFunction(std::vector<int> v, int dim) {
  return dim;
}

template<typename T>
int someFunction(std::vector<T> v, int dim) {
  return someFunction(T(), dim + 1);
}

template<typename T>
void singleFunction(std::vector<T> v) {
  int dim(someFunction(v));
  std::cout << dim << std::endl;
  // Do something
}

int main() {
  std::vector<std::vector<std::vector<int>>> v {{{1, 0}, {2, 4}}, {{2, 2}, {3, 0}}};
  singleFunction(v);
  singleFunction(std::vector<std::vector<int>>());
  singleFunction(std::vector<int>());
  return 0;
}

这里创建一个值类型的新对象并调用自身,直到其值类型为int。每次增加尺寸。

答案 1 :(得分:3)

也许你可以尝试这种方法,我认为这正是你所要求的(从std::rank采用):

#include <iostream>
#include <vector>
#include <type_traits>

template<typename T>
struct vector_rank : public std::integral_constant<std::size_t, 0> {};

template<typename T>
struct vector_rank<std::vector<T>> : public std::integral_constant<std::size_t, vector_rank<T>::value + 1> {};

template<typename T>
size_t GetVectorRank(T)
{
    return vector_rank<T>::value;
}

int main()
{
    std::vector<std::vector<std::vector<std::vector<std::vector<int>>>>> v1;
    std::cout << GetVectorRank(v1) << std::endl;
    std::vector<std::vector<std::vector<int>>> v2;
    std::cout << GetVectorRank(v2) << std::endl;
    return 0;
}

第二个模板是递归选择的,而类型是std::vector<T>,第一个模板将被选择用于其他所有内容以及递归结束时。上面的例子将返回:

5
3

演示:https://ideone.com/CLucGA

答案 2 :(得分:2)

使用C++17,您可以编写一个非常简单的解决方案:

template<typename T >
constexpr int func(){
  if constexpr (is_vector<typename T::value_type>::value )
   return 1+func<typename T::value_type>();
  return 1;
}

int main() {
    cout<< func<vector<vector<vector<vector<vector<int>>>>>>() <<endl;
    return 0;
}

按预期返回5

您需要按如下方式定义is_vector

template<class T>
struct is_vector{
     static bool const value = false;   
};
template<class T>
struct is_vector<std::vector<T> > {
  static bool const value = true;
};

答案 3 :(得分:1)

一个简单的模板应该解决这个问题。来自记忆:

template <T> singleFunction(vector<T> &t) {
    return t.size();
}

答案 4 :(得分:1)

您可以使用此代码获取维度

#include <vector>
#include <iostream>

template<unsigned N, typename T>
struct meta {
    static unsigned func() {//terminale recursion case
        return N;
    }
};

template<unsigned N, typename T>
struct meta<N, std::vector<T> > {//mid recursion case
    static unsigned func() {
        return meta<N + 1, T>::func();
    }
};

template<typename T>
unsigned func(T) { //adapter to deduce the type
    return meta<0, T>::func();
}

int main() {
  std::cout << func(std::vector<std::vector<std::vector<int> > >()) << std::endl;
  std::cout << func(std::vector<int>()) << std::endl;
  std::cout << func(int()) << std::endl;
  std::cout << func(std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<int> > > > > >()) << std::endl;
  return 0;
}

将输出

3
1
0
6