C++ 在类模板方法中,使用enable_if检查两个函数参数是std::array还是std::vector

C++ 在类模板方法中,使用enable_if检查两个函数参数是std::array还是std::vector,c++,arrays,templates,vector,typetraits,C++,Arrays,Templates,Vector,Typetraits,我不是一个专业的编码员,如果我的问题太幼稚或格式不正确,我道歉 我试图让类成员函数在参数中采用std::array或std::vector。 具体地说,我传递的两个参数要么都是std::array,要么都是std::vector 在尝试实现上述功能之前,我所做的最低设置仅用于std::vector参数。最小设置如下所示,其中v和p是我希望作为向量或数组传递的设置: // original version class my_class_A{ // stuf }; class my_class_

我不是一个专业的编码员,如果我的问题太幼稚或格式不正确,我道歉

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

在尝试实现上述功能之前,我所做的最低设置仅用于
std::vector
参数。最小设置如下所示,其中vp是我希望作为向量或数组传递的设置:

// 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;
  }; 
};
当我使用main中的
std::vector
调用编译时,一切都很好。这(当然)不能用
std::array
调用编译(当然编译器会抱怨)


如果我能将模板参数
设置为
并且
Au
能够被解释为
size\u t
,那么模板就会找到一个与
std::array
调用匹配的参数。然而,这是不可能的,因为我可以有
typename
size\u t
,据我所知,这两者都不可能。因此,我的问题是,在这种情况下如何使enable_工作?

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

class I\u是\u类\u方法{
私人:
样板
无效我的方法(常数C1&v、常数C2&p、常数我的B&x类、我的B&y类){
// ...
}
公众:
void my_方法(const std::vector&v,
常数标准::矢量和p,
const my_class_B&x,
我的班级(B&y)
{my_method_priv(v,p,x,y)}
样板
void my_方法(const std::array&v,
常数标准::阵列和p,
const my_class_B&x,
我的班级(B&y)
{my_method_priv(v,p,x,y)}
};

我强烈建议使用函数重载作为最佳解决方案。然而,你说你想尝试和学习。既然是这样,请允许我在这方面演示一种方法

请注意,这有点复杂,因为您需要显式的模板参数,但是检测中没有太多的元编程涉及,并且它至少让您知道在明智的情况下如何处理类似的事情,但在这种情况下,只需使用函数重载

class I\u是\u类\u方法
{
样板
结构启用{};
样板
结构启用
{
使用类型=无效;
};
样板
结构启用
{
使用类型=无效;
};
公众:
样板
typename使能::type
我的方法(T1常数和v、T2常数和p、我的B类常数和x、我的B类常数和y)
{
//随便
}
};

Ok,向前移动。请允许我问一件事。这是否意味着我现在可以用任何向量或数组调用该方法,其中A可以是任何东西?我这样问是因为p和v在数组/向量中应该只有一个特定类型的a。@Pana是的,如果您想将类型保留为一个特定类型,那么我将更新答案。如果可能,请是!“我本应该更清楚地问我自己,我也在努力防止这种情况发生,我的oversite抱歉。”Pana更新。顺便说一句,
p
v
的长度是否相同?是的,但可以。根据您的回答,我将把
template
更改为
template
,如果您的类型如此具体,为什么不使用重载并定义两个函数而不是使用SFINAE呢?如果需要,您仍然可以在私有函数中使用模板化实现。这很有趣。我需要学习更多。我将使用重载,但感谢您向我展示这一点,正如您所指出的,我可能会在实际需要时使用它。
// 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;
  }; 
};