函数指针数组模板

Template of array of function pointers

我有几个函数,其中一些是重载的,一些是模板,例如:

void fun1 (vector<string> &a, int b);
void fun1 (vector<double> &a, int b);

template <typename t>
void fun2 (t a[], int b);

等等。我使用的每个函数都有 2 种数据类型的版本,一种是数组,另一种是向量(字符串向量、双精度向量、字符串数组和双精度数组)。问题是,我可以为指针数组创建模板吗?除了:

,还有什么方法可以做到吗?
void (*strvecfun[])(vector <string>&, long, long)={fun1, fun2};
void (*dblvecfun[])(vector <double>&, long, long)={fun1, fun2};
void (*strarrfun[])(string [], long, long)={fun1, fun2};

等等?

您可以使用

template<typename Func>
struct func_array {
  static Func *const data[];
};

template<typename Func>
Func *const func_array<Func>::data[] = { fun1, fun2 };

稍后调用

func_array<void(std::vector<double>&, long, long)>::data[0](dvec, l1, l2);
func_array<void(std::vector<string>&, long, long)>::data[1](svec, l1, l2);
// ...and so forth

自然地,这要求您要使用的所有函数的所有签名都有匹配的重载。

与其拥有 2 个实现,不如拥有一个。让您的数据采用 array_view<double>:

template<class T>
struct array_view {
  // can make this private:
  T* b = 0; T* e = 0;

  // core methods:
  T* begin() const { return b; }
  T* end() const { return e; }

  // utility methods:
  size_t size() const { return end()-begin(); }
  T& front() const { return *begin(); }
  T& back() const { return *std::prev(end()); }
  bool empty() const { return begin()==end(); }

  // core ctors:
  array_view(T* s, T* f):b(s),e(f) {};
  array_view()=default;
  array_view(array_view const&)=default;

  // derived ctors:
  array-view(T* s, size_t l):array_view(s, s+l) {};
  template<size_t N>
  array_view( T(&arr)[N] ):array_view(arr, N) {};
  template<size_t N>
  array_view( std::array<T,N>&arr ):array_view(arr.data(), N) {};
  template<class A>
  array_view( std::vector<T,A>& v ):array_view(v.data(), v.size()) {};

  // extra ctors that fail to compile if `T` is not const, but
  // are mostly harmless even if `T` is not const, and useful if
  // `T` is const.  We could do fancy work to disable them, but
  // I am lazy:
  using non_const_T = std::remove_const_t<T>;
  template<class A>
  array_view( std::vector<non_const_T,A>const& v ):array_view(v.data(), v.size()) {};
  template<size_t N>
  array_view( std::array<non_const_T,N>const&arr ):array_view(arr.data(), N) {};
  array_view( std::initializer_list<non_const_T> il ):array_view(il.data(), il.size()) {};
};

array_view 就像容器中的视图一样,可以从多个 std 容器以及原始数组隐式转换。

void fun1 (array_view<std::string> a);

a.size() 告诉你它有多长,它甚至可以在 for(:) 循环中迭代。

std::vector<T>& 比您需要的要强大得多。通过使用 array_view,我们只公开您需要的内容(访问元素),因此能够同时使用数组和容器。

如果您传入 "real" C 样式数组,它会自动推断长度。如果你改为传入一个指针(或 [] 真正的指针数组),你还必须传递长度,如:

fun1( {ptr, length} );

创建一个名为 max 的函数,它将 return 数组中最大元素的值。

函数的参数应该是数组大小的地址。

将此函数制作成模板,以便它可以处理任何数值类型的数组。