作为一个大得多的项目的一部分,my对象之一(MWE中的Thing)在其上定义了一组过滤器(filterStrong,filterWeak)。目标是使用complexFilteringProcedure**,中所有已实现的过滤器,其中用户可以通过参数选择筛选规则,而函数本身将取决于所选筛选规则的成功与否。**函数complexFilteringProcedure将对一个Thing类型的对象进行操作,并根据参数调用其私有方法之一(筛选规则)。
我通过在vector中保存所有可能的过滤器并实现一个公共过滤接口filterUsingRule来实现这一点。理想情况下,这将允许我稍后在需要时向项目添加新的筛选规则,并且只修改初始化筛选列表的setFilteringFunction。
现在,我开始编写一组新的过滤规则,并意识到所有这些规则都可以通过以相同的方式修饰当前的过滤规则来获得(softenFilter;如果这里的“修饰”是错误的表达式,请纠正我)。我记得最近读了std::bind的书,教过,太棒了。我还想在我的filteringOptions,列表中添加的所有修饰过滤规则,也就是用softenFilter修饰的每个原始过滤器。
在std::bind上读更多的文章,我认为造成问题的可能原因有两方面:
std::bind是一个模板化的混乱,绝对不是Thing::filteringFunction。this和softWeak时,我可能会绑定引用调用对象的softWeak但是,我被困在更远的地方,不知道如何找到解决我的具体问题的办法。我的主要问题是:能实现这个功能吗?(filterUsingRule的功能),而且,能优雅地实现这个功能吗?(我知道我总是可以定义一组函数bool softStrong(int param) { return softenFilter(filterStrong, param); },它可以手动地将过滤器绑定到装饰器,但我希望std::bind或一些新的C++魔术能够在这方面有所帮助)。
MWE重新创建了我已经成功完成的工作和我想要实现的目标如下:
#include <iostream>
#include <vector>
#include <functional>
class Thing{
private:
int basicFilter;
typedef bool (Thing::*filteringFunction)(int);
static std::vector<filteringFunction> filteringOptions;
bool filterStrong(int parameter) {return parameter > basicFilter*2;}
bool filterWeak(int parameter) {return parameter > basicFilter;}
bool softenFilter(filteringFunction f, int parameter){
if (!((this->*(f))(parameter)))
return (this->*(f))(parameter+2);
return true;
}
void setFilteringFunctions(void){
Thing::filteringOptions.emplace_back(&Thing::filterStrong);
Thing::filteringOptions.emplace_back(&Thing::filterWeak);
auto softStrong = std::bind(&Thing::softenFilter,
&Thing::filterStrong,
std::placeholders::_1); // ok
auto softWeak = std::bind(&Thing::softenFilter,
&Thing::filterWeak,
std::placeholders::_1); // ok
filteringOptions.emplace_back(&softStrong); // how?
filteringOptions.emplace_back(softWeak); // how?
}
public:
Thing(int basicFilter) : basicFilter(basicFilter){
if (Thing::filteringOptions.empty())
setFilteringFunctions();
}
bool filterUsingRule(int parameter, int rule = 0){
return ((int)Thing::filteringOptions.size() > rule) &&
(this->*(Thing::filteringOptions[rule]))(parameter);
}
};
std::vector <Thing::filteringFunction> Thing::filteringOptions(0);
void complexFilteringProcedure(Thing &aThing, int parameter, int rule){
// do a lot of things
if (aThing.filterUsingRule(parameter, rule))
std::cout << "Filtering with " << rule << "successful" << std::endl;
else
std::cout << "Filtering with " << rule << "failed" << std::endl;
// and some more things
}
int main(void){
Thing myThing(5), otherThing(10);
complexFilteringProcedure(myThing, 7, 0); // uses strong rule
complexFilteringProcedure(otherThing, 7, 1); // uses weak rule
complexFilteringProcedure(myThing, 7, 2); // how to do this correctly?
complexFilteringProcedure(otherThing, 7, 3); // or this?
}发布于 2018-04-05 17:07:47
您可以使用std::function
using filteringFunction = std::function<bool (Thing&, int)>;然后
void setFilteringFunctions()
{
Thing::filteringOptions.emplace_back(&Thing::filterStrong);
Thing::filteringOptions.emplace_back(&Thing::filterWeak);
auto softStrong = std::bind(&Thing::softenFilter,
std::placeholders::_1,
&Thing::filterStrong,
std::placeholders::_2
);
auto softWeak = std::bind(&Thing::softenFilter,
std::placeholders::_1,
&Thing::filterWeak,
std::placeholders::_2);
Thing::filteringOptions.emplace_back(&softStrong);
Thing::filteringOptions.emplace_back(&softWeak);
// or
Thing::filteringOptions.emplace_back([](Thing& instance, int param){
return instance.filterStrong(param + 2) });
}https://stackoverflow.com/questions/49677200
复制相似问题