对于下面的类,我如何表示指向qux
的一个实例的成员变量Bar
的指针?
struct Foo {
struct Bar {
int qux;
} bar1, bar2;
};
当我使用boost::multi_index
容器并且需要使用qux
作为密钥时需要这个,这在密钥提取器中是必需的
template<class Class,typename Type,Type Class::*PtrToMember>
struct boost::multi_index::member
答案 0 :(得分:3)
我假设打算创建一个Foo
s的boost multi_index容器,并使用qux
作为密钥。虽然qux
不是Foo
的成员,但您可以通过对成员Foo::bar1
建立索引并为有序索引提供自定义比较谓词来实现此目的。例如,如果您尝试创建ordered_unique
密钥,则可以这样写:
ordered_unique<member<Foo, Foo::Bar, &Foo::bar1>, compare_foo_bar>
其中compare_foo_bar
是Foo::Bar
的朋友,并被定义为需要:
struct compare_foo_bar
{
bool operator()(const Foo::Bar& lhs, const Foo::Bar& rhs)
{
return lhs.qux < rhs.qux;
}
};
答案 1 :(得分:2)
在您的情况下,您有Class = Foo::Bar
,Type = int
和PtrToMember = &Foo::Bar::qux
,因此这应该有效
boost::multi_index::member<Foo::Bar, int, &Foo::Bar::qux>
根据您在下面的评论,我修改了Boost.MultiIndex教程中的basic example以匹配您的用例。原始示例包含以下struct
/* an employee record holds its ID, name and age */
struct employee
{
int id;
std::string name;
int age;
employee(int id_,std::string name_,int age_):id(id_),name(name_),age(age_){}
// ...
};
multi_index
容器定义为
typedef multi_index_container<
employee,
indexed_by<
ordered_unique<
tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
ordered_non_unique<
tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
ordered_non_unique<
tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >
> employee_set;
现在,让我们修改employee
,以便employee::name
实际上是嵌套struct Bar
的成员,并说employee
包含两个Bar
实例。
struct employee
{
int id;
struct Bar
{
Bar(std::string name) : name(name) {}
std::string name;
} bar1, bar2;
int age;
// ...
};
但你不能修改这个声明
ordered_non_unique<
tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>
直接指示嵌套的struct
数据成员。相反,您需要将声明修改为
ordered_non_unique<
tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,employee::Bar,bar1)>
我们需要一种方法来对employee::Bar
个对象进行排序,因此在其定义中添加一个比较运算符
struct Bar
{
// ...
bool operator<(Bar const& other) const { return name < other.name; }
};
通过这些更改,如果您使用标记name
为容器编入索引,则会根据bar1.name
数据成员对其进行排序。
我还初始化bar2.name
以包含bar1.name
中包含的反向字符序列,并使用标记name2
添加了基于索引的选项。
答案 2 :(得分:1)
您可以诉诸user-defined key extractors:
struct Foobar1qux
{
typedef int result_type;
int operator()(const Foo &x)const{return x.bar1.qux;}
};
struct Foobar2qux
{
typedef int result_type;
int operator()(const Foo &x)const{return x.bar2.qux;}
};
typedef multi_index_container<
Foo,
indexed_by<
ordered_non_unique<Foobar1qux>,
ordered_non_unique<Foobar2qux>
>
> multi_t1;
更通用的方法是级联密钥提取器,如Boost.MultiIndex文档的one of the examples所示:
template<class KeyExtractor1,class KeyExtractor2>
struct key_from_key
{
public:
typedef typename KeyExtractor1::result_type result_type;
key_from_key(
const KeyExtractor1& key1_=KeyExtractor1(),
const KeyExtractor2& key2_=KeyExtractor2()):
key1(key1_),key2(key2_)
{}
template<typename Arg>
result_type operator()(Arg& arg)const
{
return key1(key2(arg));
}
private:
KeyExtractor1 key1;
KeyExtractor2 key2;
};
typedef multi_index_container<
Foo,
indexed_by<
ordered_non_unique<
key_from_key<
member<Foo::Bar,int,&Foo::Bar::qux>,
member<Foo,Foo::Bar,&Foo::bar1>
>
>,
ordered_non_unique<
key_from_key<
member<Foo::Bar,int,&Foo::Bar::qux>,
member<Foo,Foo::Bar,&Foo::bar2>
>
>
>
> multi_t2;