【问题标题】:class method in for_eachfor_each 中的类方法
【发布时间】:2025-12-23 08:00:06
【问题描述】:

有一个类和事件结构:

struct Foo
{
    Foo(): name("nx"), val(9) {}
    string name;
    int val;
};

class Base
{
    public:
        Base()
        {
            /*array.push_back(Foo());
            array.push_back(Foo());
            array.push_back(Foo());             //fill array Foo
            array.push_back(Foo());
            array.push_back(Foo());*/
        }
        void Define(Foo* desktop)
        {
            cout << desktop->name << " " << desktop->val << "\n";
        }

        void Oblem()
        {
            /*for(int i = 0; i < array.size(); ++i)
            {
                Define(&array[i]);
            }*/
            for_each(array.begin(), array.end(), mem_fun_ref(&Base::Define));
        }
    public:
        std::vector<Foo> array;
};

如何替换 for_each 算法中被注释掉的循环?

我现在有这些错误:

  1. 错误:不匹配调用 '(std::mem_fun1_ref_t) (Foo&)'|
  2. 候选对象是:_Ret std::mem_fun1_ref_t<_ret _tp _arg>::operator()(_Tp&, _Arg) const [with _Ret = void, _Tp = Base, _Arg = Foo*]|

【问题讨论】:

    标签: c++ algorithm foreach


    【解决方案1】:

    Base::Define 有两个参数:Foo* desktop 和一个隐含的Base* this。您需要将当前的this 绑定到Oblem 中,以获得一个只需要Foo 的函数。此外,Define 应该将其参数作为Foo&amp; desktop(或者更好的是,如果那是真实代码,Foo const&amp; desktop)。

    使用 TR1 中的标准功能(或其 Boost 实现)的完整解决方案是:

    void Define(Foo const& desktop) const
    {
        cout << desktop.name << " " << desktop.val << "\n";
    }
    
    void Oblem() const
    {
        for_each(
            array.begin(), array.end()
          , std::bind( &Base::Define, this, _1 )
        );
    }
    

    【讨论】:

    • “隐式”this 应列在其他参数之前。这将使bind 调用更有意义。
    • +1 想通了,我只是因为变量名而头疼。 :)
    • @bames53: Define 仍然有一个必须传入的隐式this 参数,这是通过Oblem 内的this 的值完成的。占位符_1 用于将每个向量元素Foo 作为Foo const&amp; 传递给Define
    • K-ballo,你可以做类似的事情只是一个函数指针而不是引用?
    • @PointsEqual:你没有得到指向成员函数的函数指针,你得到的是成员函数指针。如果Define 真的这么简单,那么它可以定义为static 来获得隐含的-unused- this 参数。
    【解决方案2】:
    class Base
    {
    public:
        Base() : array(5) {}
    
    
        void Define(Foo &desktop)
        {
            cout << desktop.name << " " << desktop.val << "\n";
        }
    
        void Oblem()
        {
            for_each(array.begin(),array.end(),[this](Foo &f) {
                Define(f);
            });
    
            // or
    
            for_each(array.begin(),array.end(),
              bind(&Base::Define,this,placeholders::_1));
        }
    
    public:
        std::vector<Foo> array;
    };
    

    【讨论】: