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
参数。最小设置如下所示,其中v和p是我希望作为向量或数组传递的设置:
// 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;
};
};