C++ std::在运行时设置选择较少或较大的比较器
我重构了一些代码,发现有两个地方可以用相同的代码编写,除了一个地方的比较器是C++ std::在运行时设置选择较少或较大的比较器,c++,stl,set,predicate,C++,Stl,Set,Predicate,我重构了一些代码,发现有两个地方可以用相同的代码编写,除了一个地方的比较器是less,另一个地方是greater。比如: double MyClass::Function1(double val) { std::set<double, less<double> > s; // Do something with s } double MyClass::Function2(double val) { std::set<double, grea
less
,另一个地方是greater
。比如:
double MyClass::Function1(double val)
{
std::set<double, less<double> > s;
// Do something with s
}
double MyClass::Function2(double val)
{
std::set<double, greater<double> > s;
// Do the same thing with s as in Function1
}
double MyClass::Function1(double val)
{
std::集s;
//用手指做点什么
}
双MyClass::Function2(双val)
{
std::集s;
//对s执行与函数1相同的操作
}
所以我想做:
double MyClass::GeneralFunction(double val, bool condition)
{
if(condition)
{
// Select greater as comparator
}
else
{
// Select less as comparator
}
set<double, comparator> s;
// common code
}
double MyClass::GeneralFunction(双val,布尔条件)
{
如果(条件)
{
//选择较大值作为比较器
}
其他的
{
//选择less作为比较器
}
设置s;
//通用代码
}
我通过使用自定义比较器函数使其正常工作,如下所示:
bool my_greater(double lhs, double rhs)
{
return lhs > rhs;
}
bool my_less(double lhs, double rhs)
{
return lhs < rhs;
}
double MyClass::GeneralFunction(double val, bool condition)
{
typedef bool(*Comparator) ( double, double);
Comparator comp = &my_less;
if (condition)
{
comp = &my_greater;
}
std::set<double, Comparator > s(comp);
//....
}
bool my_更大(双左、双右)
{
返回左侧>右侧;
}
bool my_less(双左、双右)
{
返回左侧<右侧;
}
double MyClass::GeneralFunction(双val,布尔条件)
{
typedef bool(*比较器)(双精度,双精度);
比较器comp=&my\u less;
如果(条件)
{
comp=&my\u更大;
}
标准:集合s(comp);
//....
}
但是我想使用内置的。问题是我不知道如何声明比较器并为其分配内置谓词
任何帮助都将不胜感激。为什么不这样做呢
template <typename Compare>
double MyClass::GeneralFunction(double val)
{
std::set<double, Compare> s;
//....
}
模板
双MyClass::GeneralFunction(双val)
{
std::集s;
//....
}
模板参数的模板选择不是C++处理得很好的。通过让调用者提供模板参数,尽可能多地推进编译阶段
然后,如果您确实希望在运行时选择一个包装器,则可以提供包装器:double MyClass::GeneralFunction(double val, bool condition)
{
return condition ?
GeneralFunction<std::greater<double> >(val) :
GeneralFunction<std::less <double> >(val);\
}
double MyClass::GeneralFunction(双val,布尔条件)
{
返回条件?
通用功能(val):
通用函数(val)\
}
您真的需要运行时检查吗
template <class Comp> double MyClass::Function(double val)
{
std::set<double, Comp > s;
// Do something with s
}
template double MyClass::Function(double val)
{
std::集s;
//用手指做点什么
}
即使你这样做了,你仍然可以使用
double MyClass::Function(double val, bool comp)
{
return comp ? Function<std::less<double> >(val) : Function<std::greater<double> >(val);
}
double MyClass::函数(双val,bool comp)
{
返回补偿函数(val):函数(val);
}
只需使用
std::set<double, std::function<bool(double,double)>>
问题是,您无法在此时选择比较器的类型 tuntime和
std::less
和std::greater
具有不相关的类型。
类似地,用std::less
作为比较器实例化的std::set
具有与on无关的类型,该类型使用std::greater
实例化。有
有几种可能的解决方案,但最简单的(也是唯一的一种)
涉及内在性、虚拟功能和动态分配)的研究也在进行中
你正在做的事情的台词:
class SelectableCompare
{
bool myIsGreater;
public:
SelectableCompare( bool isGreater ) : myIsGreater( isGreater ) {}
bool operator()( double d1, double d2 ) const
{
static std::less<double> const less;
return myIsGreater
? less( d2, d1 )
: less( d1, d2 );
}
};
,用于不同比较的相当明显的派生类,以及
管理内存的包装器:
class ComparatorWrapper
{
std::shared_ptr<Comparator> myComparator;
public:
ComparatorWrapper( Comparator* newed_comparator )
: myComparator( newed_comparator )
{
}
bool operator()( double d1, double d2 ) const
{
return myComparator->isLessThan( d1, d2 );
}
};
类ComparatorWrapper
{
std::共享\u ptr myComparator;
公众:
比较器包装器(比较器*新比较器)
:myComparator(新的\u比较器)
{
}
布尔运算符()(双d1,双d2)常量
{
返回myComparator->isLessThan(d1、d2);
}
};
对于您所需要的二进制选择来说,这无疑是过分的,但可能是
如果有更多的选择,则适当;e、 g.a设置
可能是
在许多不同字段中的一个字段上排序(所有字段都是不同类型的)。+1用于
std::function
。关于在使用集合时意外更改顺序的风险:任何标志都应该是函数对象的私有成员,这将极大地降低风险。std::function部分是我实际要问的,但我认为MSalters的答案是更好的解决方案。谢谢!我实际上不需要运行时检查,所以我可以在调用者中选择比较器。
class SelectableCompare
{
bool myIsGreater;
public:
SelectableCompare( bool isGreater ) : myIsGreater( isGreater ) {}
bool operator()( double d1, double d2 ) const
{
static std::less<double> const less;
return myIsGreater
? less( d2, d1 )
: less( d1, d2 );
}
};
class Comparator
{
public:
virtual ~Comparator() {}
virtual bool isLessThan( double d1, double d2 ) const = 0;
};
class ComparatorWrapper
{
std::shared_ptr<Comparator> myComparator;
public:
ComparatorWrapper( Comparator* newed_comparator )
: myComparator( newed_comparator )
{
}
bool operator()( double d1, double d2 ) const
{
return myComparator->isLessThan( d1, d2 );
}
};