【问题标题】:`for_each` not working as I expect`for_each` 没有按我的预期工作
【发布时间】:2015-11-17 03:57:53
【问题描述】:

我正在使用函数式编程的一些特性,并试图为向量中的每个对象调用一个成员函数。到目前为止,这是我的代码。

emplace.cc

#include <iostream>
#include <vector>
#include <string>
#include <functional>

class Person {
   public:
      Person(std::string name, size_t age) : _name(name), _age(age) { std::cout << "Hello, " << getName() << std::endl; }
      ~Person() { std::cout << "Goodbye, "<< getName() << std::endl; }
      void greet() { std::cout << getName() << " says hello!" << std::endl; }
      std::string getName() const { return _name; }
   private:
      std::string _name;
      size_t _age;

};

int main()
{
   std::vector<Person> myVector;
   myVector.emplace_back("Hello", 21);
   myVector.emplace_back("World", 20);

   std::for_each(myVector.begin(), myVector.end(), std::bind1st(std::mem_fun(&Person::greet), this));
   return 0;
}

这段代码很可能存在问题,但对我来说奇怪的是我正在收到两条错误消息。

emplace.cc:24:4: error: 'for_each' is not a member of 'std'
    std::for_each(myVector.begin(), myVector.end(), std::bind1st(std::mem_fun(&Person::greet), this));
    ^
emplace.cc:24:95: error: invalid use of 'this' in non-member function
    std::for_each(myVector.begin(), myVector.end(), std::bind1st(std::mem_fun(&Person::greet), this));
                                                                                               ^

我正在使用 GCC 5.2.0 编译 -std=c++14

【问题讨论】:

    标签: c++ algorithm functional-programming bind


    【解决方案1】:

    for_each&lt;algorithm&gt;

    你可以的

    for_each(myVector.begin(), myVector.end(), [&] (const decltype(myVector.front())& a) { a.greet(); });
    

    【讨论】:

    • 我刚刚添加了如何解决这个问题:)
    • 太好了!我会将其标记为已接受。 bind 有什么好的方法吗?没关系,只要它有效,只是好奇。
    • c++14 中的 lambda 可能是这样的:[](auto el) { el.greet(); }
    • 之前没用过bind哈哈。但我认为 bind 用于不提供函数参数的情况。但是在for_each 中,对第三个参数的函数调用在它的实现中被调用时会给出一个参数,所以我认为你不会想在这里使用bind。但也许尝试删除bind
    • @erip 我认为您不需要绑定。 std::for_each(myVector.begin(), myVector.end(), std::mem_fun(&amp;Person::greet)); 应该可以工作。自 c++11 以来,现在也不推荐使用 bind1st。请改用绑定和占位符。
    【解决方案2】:

    首先你忘了包含标题&lt;algorithm&gt;。在这种情况下你不能使用this

    试试下面的

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <functional>
    
    
    class Person {
       public:
          Person(std::string name, size_t age) : _name(name), _age(age) { std::cout << "Hello, " << getName() << std::endl; }
          ~Person() { std::cout << "Goodbye, "<< getName() << std::endl; }
          void greet() { std::cout << getName() << " says hello!" << std::endl; }
          std::string getName() const { return _name; }
       private:
          std::string _name;
          size_t _age;
    
    };
    
    int main()
    {
       std::vector<Person> myVector;
       myVector.emplace_back("Hello", 21);
       myVector.emplace_back("World", 20);
    
       std::for_each(myVector.begin(), myVector.end(), std::mem_fn( &Person::greet ) );
    }
    

    程序输出是

    Hello, Hello
    Hello, World
    Goodbye, Hello
    Hello says hello!
    World says hello!
    Goodbye, World
    Goodbye, Hello
    

    如果在向量定义之后包含以下调用

    std::vector<Person> myVector;
    myVector.reserve( 2 );    
    

    那么输出将是

    Hello, Hello
    Hello, World
    Hello says hello!
    World says hello!
    Goodbye, World
    Goodbye, Hello
    

    即添加第二个元素时不会重新分配内存。

    【讨论】:

    • 有趣。析构函数在输出的第三行被调用,因为我没有实现移动构造函数,我想?
    • @erip 您没有为向量的两个元素保留内存。因此,当添加第二个元素时,向量会重新分配其内存范围。
    • std::mem_fun 而不是 fn?
    • 不,是std::mem_fn
    • 是的。我不知道 mem_fn。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 2021-01-01
    相关资源
    最近更新 更多