我有一个 std::vector
指针 Person
对象,它有一个成员函数 std::string getName() const
。我想使用 STL 算法计算 vector 中的所有 Person
对象,其中 getName()
返回“Chad”。
简单迭代循环的行为是:
int num_chads = 0;
for(std::vector<Person *>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
if((*it)->getName() == "Chad")
++num_chads;
}
我想重新设计它,使其使用所有 STL 算法和仿函数等(使其更面向功能)。这是我认为我需要做的:
const int num_chads = std::count_if(vec.begin(), vec.end(),
std::bind1st(std::bind2nd(std::equal_to, mem_fun(Person::getName)), "Chad"));
您可能会说这是行不通的。首先,据我了解,您不能在 binder1st/binder2nd 对象上使用 bind1st/bind2nd,因为它们专门设计用于 std::binary_functions
。其次,更重要的是,我认为我没有使用正确的技术。我确实想将其中一个参数绑定(bind)到“Chad”,但是对于迭代器参数,我实际上只想在调用 equals_to的绑定(bind)版本之前将迭代器值转换为字符串
.
我认为使用 Boost 可以做到这一点,但是否可以只使用核心 C++03(即没有 C++0x lambas!)?
编辑:谁能想出一个不使用用户定义谓词的示例(即仅使用标准工具包中提供的工具)?
编辑:虽然 Matthieu 的回答是关于如何在 STL 算法中使用仿函数的教科书答案,但 Cubbi 的回答来 self 正在寻找的方法(尽管 Mathieu 在我编辑问题以使其更具体之前确实回答了,所以在此道歉!)。
最佳答案
我一直觉得 lambda 相对难读。我更喜欢写显式类型:
struct Named
{
Named(char const* ref): _ref(ref) {}
bool operator()(Person* p) const { return p && p->getName() == _ref; }
char const* _ref;
};
size_t const c = std::count_if(vec.begin(), vec.end(), Named("Chad"));
尽管 Named
的定义是“越界”的,但正确选择的名称可以传达意图并隐藏实现细节。就个人而言,我认为这是一件好事,因为那样我就不会被实现细节分散注意力,也不会试图通过对代码进行逆向工程来弄清楚发生了什么(尽管它可能很明显)。
关于c++ - 返工 for 循环 STL 容器以使用功能技术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5325122/