c++ - 对非原始对象使用 boost 过滤器迭代器

标签 c++ boost

假设我有一个从 Boost 的 Multi-Index 返回的迭代器,其中每条记录都包含一个年龄和一个姓名字段。

我得到迭代器

auto& index = get<age>(m_records);
auto ibegin = index.begin();
auto iend = index.end();

我如何将这个迭代器与 Boost 的过滤器迭代器一起使用,以便我可以返回所有记录,比如 name = "John"?

我为谓词运算符设置了一个结构,我不确定它是否正确:

struct name_equal_to {
      std::string struct_sname;
      bool operator()(ServerRecord x) { return x.get_name() == struct_sname; }
      name_equal_to(std::string in) : struct_sname(in){}
   };

最佳答案

我会使用过滤适配器,使内容更具可读性:

for (auto& r : get<age>(m_records) | filtered(name_equal_to("John"))
    std::cout << r << "\n";

我会在风格上改进仿函数 ( Live On Coliru ):

struct name_equal_to {
    bool operator()(ServerRecord const& x) const { 
        return x.get_name() == sname_; 
    }
    name_equal_to(std::string in) : sname_(std::move(in)){}
  private:
    std::string sname_;
};

为了让它真正优雅,使用 Phoenix 就地定义谓词 named_john:

auto named_john = phx::bind(&record::name, arg1) == "John";

查看 Live On Coliru ,它打印按年龄索引排序的两条记录:

2 John 40
4 John 57

完整示例代码

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>

using boost::multi_index_container;
using namespace boost::multi_index;

struct record {
    int         id;
    std::string name;
    int         age;

    friend std::ostream& operator<<(std::ostream& os,const record& e) {
        return os << e.id << " " << e.name << " " << e.age;
    }
};

typedef multi_index_container<
  record,
  indexed_by<
    ordered_unique<tag<struct id>      , BOOST_MULTI_INDEX_MEMBER(record, int        , id)>   ,
    ordered_non_unique<tag<struct name>, BOOST_MULTI_INDEX_MEMBER(record, std::string, name)> ,
    ordered_non_unique<tag<struct age> , BOOST_MULTI_INDEX_MEMBER(record, int        , age)> >
> employee_set;


employee_set get_records()
{
    employee_set es;

    es.insert(record{ 0,       "Joe",   31 });
    es.insert(record{ 1,    "Robert",   27 });
    es.insert(record{ 2,      "John",   40 });
    // next insertion will fail, as there is an record with the same ID
    es.insert(record{ 2, "Aristotle", 2387 });
    es.insert(record{ 3,    "Albert",   20 });
    es.insert(record{ 4,      "John",   57 });

    return es;
}

#include <boost/phoenix.hpp>
#include <boost/range/adaptors.hpp>
namespace phx = boost::phoenix;
using namespace phx::arg_names;
using boost::adaptors::filtered;

int main()
{
    auto const m_records = get_records();

    auto named_john = phx::bind(&record::name, arg1) == "John";

    for (auto& r : get<age>(m_records) | filtered(named_john)) {
        std::cout << r << "\n";
    };
}

关于c++ - 对非原始对象使用 boost 过滤器迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24871245/

相关文章:

c++ - 在 FPS 风格游戏中使用鼠标输入时运动意外加速

c++ - boost::io_service 如何保证处理程序的执行顺序

php - C++ 的功能是否比 PHP 少?

c++ - STL 中令人烦恼的解析 scott meyers

c++ - 如何使用内部函数 C++ 将 3 个加法和 1 个乘法转换为矢量化 SIMD

c++ - Boost Asio串口问题

C++ getter/setter、互斥量、细粒度锁定

c++ - 模板类型定义的新 "using"语法解决了什么问题?

c++ - 带有 boost::shared_ptr 的 static_cast?

c++ - 如何在 VS 2008 中安装 boost?