首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用功能技术对STL容器上的循环进行返工

使用功能技术对STL容器上的循环进行返工
EN

Stack Overflow用户
提问于 2011-03-16 12:16:15
回答 3查看 610关注 0票数 8

我有一个指针std::vector Person对象,它有一个成员函数std::string getName() const。使用STL算法,我希望计数向量中的所有Person对象,getName()返回"Chad“。

简单地在循环上迭代的行为是:

代码语言:javascript
复制
int num_chads = 0;
for(std::vector<Person *>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
    if((*it)->getName() == "Chad")
        ++num_chads;
}

我想重做这个,所以它使用了所有的STL算法和函子等(使它更加面向功能)。我认为我需要做的是:

代码语言:javascript
复制
const int num_chads = std::count_if(vec.begin(), vec.end(),
                                    std::bind1st(std::bind2nd(std::equal_to, mem_fun(Person::getName)), "Chad"));

你可能知道这不管用。首先,据我所知,您不能在bind1st 1/binder2对象上使用bind1st 1/bind2,因为它们是专为使用std::binary_functions而设计的。其次,更重要的是,我认为我没有使用正确的技术。我确实想将其中一个参数绑定到“乍得”,但使用迭代器参数,我实际上只想在调用绑定版本的equals_to之前将迭代器值转换为字符串。

我认为使用Boost可以做到这一点,但是是否可以只使用核心C++03 (即不使用C++0x!)?

编辑:谁能想出一个不使用用户定义谓词的例子(即仅仅使用std工具包中提供的工具)?

编辑:虽然Matthieu的答案是关于如何在STL算法中使用函子的教科书答案,但Cubbi的答案来自于我正在寻找的方法(尽管Mathieu在编辑这个问题之前就已经回答了,以便使它更加具体,所以请原谅!)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-16 14:29:02

由于还没有人发布实际的boost代码,所以使用boost的C++98:

代码语言:javascript
复制
ptrdiff_t num_chads = std::count_if(vec.begin(), vec.end(),
                      boost::bind(&Person::getName, _1) == "Chad");

测试运行https://ideone.com/PaVJe

至于纯C++,我认为没有compose1适配器是不可能的,它存在于STL中,但在C++ stdlib中却没有.

这里是(使用GCC的STL实现)

代码语言:javascript
复制
ptrdiff_t num_chads = std::count_if(vec.begin(), vec.end(),
                     __gnu_cxx::compose1(
                         std::bind2nd(std::equal_to<std::string>(), "Chad"),
                         std::mem_fun(&Person::getName)));

测试运行:https://ideone.com/EqBS5

编辑:更正为Person*帐户

票数 5
EN

Stack Overflow用户

发布于 2011-03-16 13:24:24

我一直觉得兰巴达比较难读。我更喜欢写显式类型:

代码语言:javascript
复制
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的定义是“越界的”,但正确选择的名称传达了意图,并隐藏了实现细节。就我个人而言,我认为这是一件好事,因为这样我就不会因为实现细节而分心,也不会试图通过逆向工程来找出代码正在发生的事情(尽管这可能是显而易见的)。

票数 9
EN

Stack Overflow用户

发布于 2011-03-16 13:36:36

使用boost::bind,它在某种程度上优于现有的标准绑定机制。boost::bind完全兼容C++03。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5325122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档