【问题标题】:Call member function on each element in a container在容器中的每个元素上调用成员函数
【发布时间】:2009-04-05 14:52:24
【问题描述】:

这个问题是风格问题,因为你总是可以写一个 for 循环或类似的东西;但是,是否有一个不那么突兀的 STL 或 BOOST 相当于写作:

for (container<type>::iterator iter = cointainer.begin();
     iter != cointainer.end();
     iter++)
 iter->func();

?

类似(想象的)这样的:

call_for_each(container.begin(), container.end(), &Type::func);

如果您决定更改基本类型/容器类型,我认为这将是 1) 更少的输入,2) 更易于阅读,3) 更少的更改。

编辑: 感谢您的帮助,现在,如果我想将一些参数传递给成员函数怎么办?

【问题讨论】:

    标签: c++ stl boost coding-style


    【解决方案1】:
     #include <algorithm>  // for_each
     #include <functional> // bind
    
     // ...
    
     std::for_each(container.begin(), container.end(), 
                       std::bind(&Type::func));
    

    有关详细信息,请参阅 std::for_eachstd::bind 文档。

    错过了您的编辑:无论如何,如果需要的话,这是另一种在不使用 Boost 的情况下实现您想要的方式:

    std::for_each(foo_vector.begin(), foo_vector.end(),
        std::bind(&Foo::func, std::placeholders::_1));
    

    【讨论】:

    • +1。或者 mem_fun_ref 如果容器包含对象而不是指向它们的指针
    • @litb:谢谢,我对 BOOST_FOREACH 和 mem_fun_ref() 都犹豫了。我永远无法决定何时写得太多或太少:P
    【解决方案2】:

    您可以使用std::for_eachboost's foreach constructs

    当您不想将逻辑移到另一个函数中时,请使用 boost 的 BOOST_FOREACH 或 BOOST_REVERSE_FOREACH。

    【讨论】:

    • +1。 BOOST_FOREACH(类型 &t, 容器) t.func();看起来确实很整洁
    【解决方案3】:

    我发现 boost bind 似乎很适合这个任务,另外你可以给方法传递额外的参数:

    #include <iostream>
    #include <functional>
    #include <boost/bind.hpp>
    #include <vector>
    #include <algorithm>
    
    struct Foo {
        Foo(int value) : value_(value) {
        }
    
        void func(int value) {
            std::cout << "member = " << value_ << " argument = " << value << std::endl;
        }
    
    private:
        int value_;
    };
    
    int main() {
        std::vector<Foo> foo_vector;
    
        for (int i = 0; i < 5; i++)
            foo_vector.push_back(Foo(i));
    
        std::for_each(foo_vector.begin(), foo_vector.end(),
            boost::bind(&Foo::func, _1, 1));
    }
    

    【讨论】:

    • +1 因为你用那个绑定答案击败了我 5 分钟:p(哦,std::mem_fun_ref 与绑定参数一起使用时是垃圾!)
    • +1,用于自行解决此问题并使用 Boost。干杯!
    • 我的意思是当你有引用到引用时,当你有成员函数有一个引用参数时。 boost::bind 很好地解决了它:)
    【解决方案4】:

    由于 C++11 标准,BOOST 方法被标准化为不同的语法,如“基于范围的循环”:

    class Foo {
        Foo(int x);
        void foo();
    }
    vector<int> list = {Foo(1),Foo(2),Foo(3)};
    for(auto &item: list) item.foo();
    

    【讨论】:

      【解决方案5】:

      如果您真的想提高性能而不仅仅是美化您的代码,那么您真正需要的是 map 函数。 Eric Sink 写了一个.net implementation

      【讨论】:

      • 谢谢,我正在寻找通用 C++(平台无关)解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-26
      • 2012-01-14
      • 2011-03-23
      相关资源
      最近更新 更多