使用Boost Filter迭代器处理非基元对象
Using Boost Filter Iterator with non-Primitive Objects
假设我有一个从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";
};
}
@sehe的答案绝对正确,但是如果你关心效率,那么这不是按年龄排序检索所有Johns的最快方法。假设您的容器有N个元素,其中有M个 Johns。所以:
- 遍历所有按年龄排序并按"John"过滤的元素需要N步。
- 检索所有Johns并按年龄排序(如您在其他帖子中讨论的)需要(大致)2·log(N)步骤来检索Johns的范围,临时向量的一次分配,M步骤来填充它,O(M·log(M))来排序它,M遍历它。
,它是O (N )和O (log (N ) + M·日志())。我打赌#2比#1快,M <<N,我认为这是通常的情况(当然您应该测量您的实际程序)。
相关文章:
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何使用对C函数和类对象的外部调用来处理C++头文件
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 使用对象数组对 SFML 进行动画处理
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- 使用对象的基类部分模板专用化对对象进行哈希处理::哈希
- C++:处理线程本地对象销毁
- 传递多处理.将对象值为 ctype 函数?
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 使用返回对象的函数处理错误
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 处理从列表中删除指向对象的指针的"healthy"方法是什么?
- C++如何处理同名对象的向量?
- static是如何使用ClassA::m_variable处理所有类对象的
- 当线程处理不同的类时,应该在哪里声明条件变量、互斥对象
- 处理无法按预期方式创建的对象,c++
- 我可以将类作为C 中的对象处理
- QT良好的全局变量/对象处理
- 如何将map和unordered_map作为同一对象处理
- 强制一个对象处理输入的信号