调用 C++ 向量的每个元素的成员函数

Posted

技术标签:

【中文标题】调用 C++ 向量的每个元素的成员函数【英文标题】:Calling a member function of every element of a C++ vector 【发布时间】:2012-05-09 13:09:58 【问题描述】:

假设有一个类对象的向量。

vector<Object1> vec;

说,Object1 有一个成员函数void foo(Object2*)

我想做以下事情:

for(int i=0; i<vec.size(); i++) 
    vec[i].foo(obj2);

如何在不使用显式循环的情况下做到这一点?

【问题讨论】:

使用循环有什么问题? @giorashc,总是更喜欢算法而不是循环。虽然,目前有基于远程的。 @giorashc 没有错。就像有 for_each 对向量的元素应用函数一样,我想知道是否有某种方法可以为向量的每个元素调用成员函数。 @chris: 你在说什么算法???他的问题没有任何逻辑,只是纯粹的语法问题 @Bhargava 不,问题不同。请再看看。 【参考方案1】:

使用 TR1/C++11 最简单:

#include <vector>
#include <functional>
#include <algorithm>

struct Object2;

struct Object1 
  void foo(Object2*) 
;

int main() 
  std::vector<Object1> vec;
  Object2 obj2;
  std::for_each(vec.begin(), vec.end(), std::bind(&Object1::foo, std::placeholders::_1, &obj2));

但您也可以将std::for_eachstd::bind2ndstd::mem_fun_ref 一起使用,如果这不是一个选项:

std::for_each(vec.begin(), vec.end(), std::bind2nd(std::mem_fun_ref(&Object1::foo), &obj2));

【讨论】:

for_each 不算循环吗? 这不是一个显式循环:) @LuchianGrigore,这是一种算法,应该优于普通循环。 @Benj - 对我来说,优点是:a)使意图更清晰。我所做的主要是关于数据,而不是控制结构,这强调了 b)我不会因为在循环的每次迭代中在容器上调用 .end() 而被唠叨(有些人喜欢抱怨这一点) c) 更难出现意外的拼写错误 其他 C++11 版本:std::for_each(vec.begin(), vec.end(), [&amp;obj2](Object1 &amp;o) o.foo(obj2); );for (auto &amp;o : vec) o.foo(obj2); 。如果有人愿意争辩说后者是一个“显式循环”,因此比使用算法“不太清楚”,那么让我们听听吧;-)【参考方案2】:

一种较旧的风格是手动编写仿函数。对于更复杂的逻辑,这允许您将整个班级专门用于解决问题。

class fancyFunctor

  Object2* m_data;

public:
  fancyFunctor(Object2 * data) : m_data(data)

  operator()(Object1 & ref) 
  
    ref.foo(m_data) 
  

然后迭代:

std::for_each(vec.begin(),vec.end(), fancyFunctor(&randomObject2));

【讨论】:

【参考方案3】:

此类代码的可读性并不完美,并且不能以任何简单的单行方式完成。 这是因为,某个类的成员方法的第一个参数是指向该类的对象的指针,将在该对象上执行。

或者,您可以使用新 C++11 标准附带的 foreach 循环(但它仍然是循环)。

【讨论】:

你会注意到我的答案对于 C++11 和 C++98/03 都有一个简单的单行方式,尽管有指针。 是的,你是对的——我的错。没有考虑 C++11/tr1 绑定(起初我应该阅读你的整篇文章)。

以上是关于调用 C++ 向量的每个元素的成员函数的主要内容,如果未能解决你的问题,请参考以下文章

C++如何调用使用向量的成员函数

C++ - 没有匹配的成员函数调用“push_back”

用向量 c++ 中的指针成员初始化对象

在 C++ 向量的每个元素上调用函数

使用非静态成员函数的 C++ 排序向量

C ++根据成员函数从向量中擦除对象[重复]