c++ - 持有成员函数指针和装饰成员函数指针的集合

标签 c++ c++11 pointer-to-member

作为一个更大项目的一部分,我的一个对象(MWE 中的 Thing)定义了一组过滤器(filterStrongfilterWeak)。 目标是使用 complexFilteringProcedure 中所有已实现的过滤器,用户可以通过参数选择过滤规则,函数本身将取决于选择的过滤规则是否成功。函数complexFilteringProcedure将作用于 Thing 类型的对象,并根据参数调用其私有(private)方法之一(过滤规则)。

我通过持有 vector 来实现这一点filteringOptions 中所有可能的过滤器并实现一个公共(public)过滤接口(interface),filterUsingRule .理想情况下,这将允许我稍后根据需要向项目添加新的过滤规则,并且只修改 setFilteringFunction过滤器列表被初始化的地方。

现在,我开始编写一组新的过滤规则,并意识到所有这些都可以通过以相同的方式装饰当前的过滤规则来获得(softenFilter;如果“装饰”是错误的,请纠正我此处表达)。我记得读过 std::bind最近又受教了,太好了。 我还想在我的 filteringOptions 列表中添加所有修饰过滤规则,即每一个用softenFilter修饰的原始过滤器.

阅读更多关于 std::bind 的内容,我认为我的问题可能有两个原因:

  • std::bind 的返回类型是一个模板化的困惑,绝对不是 Thing::filteringFunction
  • 我可能会绑定(bind) this在定义 softStrong 时引用调用对象和 softWeak

但是,我被困得更深了,不确定如何为我的特定问题寻找解决方案。我的主要问题是:可以实现这个功能吗?(filterUsingRule 的功能)并且可以优雅地实现这个功能吗?(我知道我总是可以定义一个一组函数 bool softStrong(int param) { return softenFilter(filterStrong, param); } 手动将过滤器绑定(bind)到装饰器,但我希望 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?
}

最佳答案

您可以使用 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) });
}

关于c++ - 持有成员函数指针和装饰成员函数指针的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49677200/

相关文章:

c++ - 移动语义和 const 引用

c++ - 指向成员函数的指针 - 不想工作

c++ - 依赖基类中的常量使外部定义不匹配?

c++ - 如何获得指向类的复制构造函数的成员函数指针?

C++ 指向成员函数的指针、声明

C++ 和 GCC : How Does GCC's C++ Implementation Handle Division by Zero?

c# - 如何在 C# 项目中使用 Clang?

c++11 - 省略号可以/应该/将适用于元组吗?

c++ - 使用基类的 ADL swap

c++ - 从另一个方法调用 map 上的方法