[英]pointer to member variable in nested struct
For the below class, how do I represent the pointer to the member variable qux
of one of the instances of Bar
? 对于下面的类,我如何表示指向Bar
实例之一的成员变量qux
的指针?
struct Foo {
struct Bar {
int qux;
} bar1, bar2;
};
This is needed when I use the boost::multi_index
container and need to use qux
as the key, which is needed in the key extractor 当我使用boost::multi_index
容器并且需要使用qux
作为密钥时,这是必需的,这在密钥提取器中是必需的
template<class Class,typename Type,Type Class::*PtrToMember>
struct boost::multi_index::member
I am assuming the intention is to create a boost multi_index container of Foo
s and use qux
as the key. 我假设的目的是创建一个Foo
的boost multi_index容器,并使用qux
作为键。 Though qux
isn't a member of Foo
, you can achieve this by indexing on the member Foo::bar1
and providing a custom comparison predicate for the ordered index. 尽管qux
不是Foo
的成员,但您可以通过在成员Foo::bar1
上建立索引并为有序索引提供自定义比较谓词来实现此目的。 For example, if you are trying to create an ordered_unique
key, you would write it like this: 例如,如果您尝试创建ordered_unique
键,则可以这样编写:
ordered_unique<member<Foo, Foo::Bar, &Foo::bar1>, compare_foo_bar>
where compare_foo_bar
is a friend of Foo::Bar
and is defined as need: 其中compare_foo_bar
是Foo::Bar
的朋友,并根据需要进行定义:
struct compare_foo_bar
{
bool operator()(const Foo::Bar& lhs, const Foo::Bar& rhs)
{
return lhs.qux < rhs.qux;
}
};
In your case you have Class = Foo::Bar
, Type = int
and PtrToMember = &Foo::Bar::qux
, so this should work 在您的情况下,您具有Class = Foo::Bar
, Type = int
和PtrToMember = &Foo::Bar::qux
,因此这应该可行
boost::multi_index::member<Foo::Bar, int, &Foo::Bar::qux>
Based on your comment below, I modified the basic example from the Boost.MultiIndex tutorial to match your use case. 根据您在下面的评论,我修改了Boost.MultiIndex教程中的基本示例以匹配您的用例。 The original example contains the following struct
原始示例包含以下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_){}
// ...
};
And the multi_index
container is defined as 并且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;
Now, let us modify employee
so that employee::name
is actually a member of a nested struct Bar
, and say employee
contains two instances of Bar
. 现在,让我们修改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;
// ...
};
But you can't modify this declaration 但是你不能修改这个声明
ordered_non_unique<
tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>
to indicate the nested struct
's data member directly. 直接指示嵌套struct
的数据成员。 Instead, you need to modify the declaration to 相反,您需要将声明修改为
ordered_non_unique<
tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,employee::Bar,bar1)>
We need a way to order the employee::Bar
objects, so add a comparison operator to its definition 我们需要一种方法来订购employee::Bar
对象,因此在其定义中添加一个比较运算符
struct Bar
{
// ...
bool operator<(Bar const& other) const { return name < other.name; }
};
With these changes, if you index into the container using the tag name
, you'll be ordering it based on the bar1.name
data member. 进行这些更改后,如果您使用标签name
索引到容器中,则将根据bar1.name
数据成员对其进行排序。
Here's a complete working example . 这是一个完整的工作示例 。
I also initialized bar2.name
to contain the reverse sequence of characters as that contained in bar1.name
, and added the option to index based on that using the tag name2
. 我还初始化bar2.name
含有包含在字符为的反向序列bar1.name
,并加入基于该使用标记的选项索引name2
。
You can resort to 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;
A more generic approach is to cascade key extractors as shown in one of the examples of Boost.MultiIndex documentation: 一种更通用的方法是级联键提取器,如Boost.MultiIndex文档的示例之一所示:
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.