c++ - 在类模板方法中使用enable_if来检查两个函数参数是否都是std::array或都是std::vector

标签 c++ arrays templates vector type-traits

我不是专业编码员,如果我的问题显得幼稚或格式错误,我深表歉意。

我试图让类成员函数在参数中采用 std::arraystd::vector 。 具体来说,我传递两个参数,它们要么都是 std::array ,要么都是 std::vector

在尝试实现上述工作之前,我所拥有的最低设置仅适用于 std::vector 参数。最小设置如下,其中 vp 是我希望作为 vector 或数组传递的内容:

// original version

class my_class_A{
// stuf
};

class my_class_B{
// other stuf
};

class I_am_a_class_of_methods{
public:
  inline void my_method(const std::vector<my_class_A> &v,
                        const std::vector<std::array<uint64_t,2> > &p,
                        const my_class_B &x,
                        my_class_B &y){
    // `v` and `p` are used to modify `x` and store the result in `y`
    return;
  }; 
};

我知道我可以通过函数重载来做我想做的事情,但是,我决定使用 templatesstd::enable_if 来实现所需的结果,以强制我想更多地了解他们。好吧,我确实学到了很多我不知道的东西……但似乎还不够。 我基本上尝试设置一个特征 is_both_array_or_vector,并且 std::enable_if 将检查模板调用是否与该特征匹配。我尝试的最后一件事是下面的,它确实编译了,但它只适用于 std::vector:

// current version

class my_class_A{
// stuf
};

class my_class_B{
// other stuf
};

// set up a type trait to check if both are vector or both are array
template <typename T1, typename T2>                                                                                                                                                                         
struct is_both_array_or_vector{                                                                                                                                                                             
  enum { value = false };                                                                                                                                                                                   
};                                                                                                                                                                                                          

template <typename T1, typename T2, typename A1, typename A2 >                                                                                                                                              
struct is_both_array_or_vector<std::vector<T1, A1>, std::vector<T2, A2> > {                                                                                                                                 
  enum { value = true };                                                                                                                                                                                    
};                                                                                                                                                                                                          

template <typename T1, typename T2, size_t D>                                                                                                                                                               
struct is_both_array_or_vector<std::array<T1, D>, std::array<T2, D> > {                                                                                                                                     
  enum { value = true };                                                                                                                                                                                    
}; 

// conditionally compile with enable_if
class I_am_a_class_of_methods{
public:
  template<template<typename,typename> U, template<typename,typename> S,
           typename Au, typename As> 
  typename std::enable_if<is_both_array_or_vector<U<my_class_A, Au>, S<std::array<uint64_t,2>,As> >::value >::type
  my_method(const U<my_class_A, Au> &v,
            const S<std::array<uint64_t,2>, As> &p,
            const my_class_B &x,
            my_class_B &y){
    // `v` and `p` are used to modify `x` and store the result in `y`
    return;
  }; 
};

当我使用来自 main 的 std::vector 调用进行编译时,一切正常。这(当然)不会通过 std::array 调用进行编译(编译器当然会提示)。

如果我能让模板参数 AsAu 能够被解释为 size_t,那么模板就会找到与std::array 调用。然而,这是不可能的,因为我可以有 typenamesize_t,但据我所知,不能同时拥有两者。因此我的问题是,如何让enable_if在这种情况下工作?

最佳答案

更新:正如哈维尔所说,您可以保留一个私有(private)函数模板来处理一般情况,并为您想要的类型重载两个方法并将它们传递给该模板。

class I_am_a_class_of_methods {
private:
  template <typename C1, typename C2>
  void my_method_priv(const C1& v, const C2& p, const my_class_B& x, my_class_B& y) {
    // ...
  }

 public:
  void my_method(const std::vector<my_class_A>& v,
                 const std::vector<array<uint64_t, 2>>& p,
                 const my_class_B& x,
                 my_class_B& y)
  { my_method_priv(v, p, x, y); }

  template <size_t N1, size_t N2>
  void my_method(const std::array<my_class_A, N1>& v,
                 const std::array<std::array<uint64_t, 2>, N2>& p,
                 const my_class_B& x,
                 my_class_B& y)
  { my_method_priv(v, p, x, y); }
};

关于c++ - 在类模板方法中使用enable_if来检查两个函数参数是否都是std::array或都是std::vector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60960573/

相关文章:

javascript - 通过 ajax 将命名数组发送到 PHP

javascript - 如何在 Javascript 中获取一个数组的任何元素在另一个数组中出现的次数?

ios - 基于窗口的应用程序和基于 View 的应用程序有什么区别?

templates - Dojo 和模板解决方案

c++ - 链表构造中,开头加一个变量的代码是什么?

c++ - 我目前正在使用什么 c++ norme?

javascript - 服务器上的 Node.js 对象不是客户端上的对象

c++ - C++中如何区分数据结构模板和函数模板?

c# - 如何将struct中的char *从c#传递到c++

c++ - 函数原型(prototype)中的参数