如何使用find()和end()测试boost multi_index是否返回了一个元素



我已经有几年没有使用c++了,正在努力实现boost multi_index容器。我生成了一个玩具,在这里演示了我的问题:http://cpp.sh/6q4nb,并且(经过一些键入(我在这里重新创建了该代码:

#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
class Placeholder {
public:
const uint64_t& getPlaceholderTime( void )  const   { return ph_time; }
const std::string& getPlaceholderId( void ) const   { return ph_id; }
private:
uint64_t ph_time;
std::string ph_id;
};
struct IndexByPlaceholderId { };
typedef boost::multi_index_container<
Placeholder,
boost::multi_index::indexed_by
<boost::multi_index::ordered_non_unique< boost::multi_index::identity<Placeholder> >
,boost::multi_index::ordered_non_unique<
boost::multi_index::const_mem_fun<
Placeholder,
const uint64_t&,
&Placeholder::getPlaceholderTime
>
>
,boost::multi_index::ordered_non_unique<
boost::multi_index::tag<IndexByPlaceholderId>,
boost::multi_index::const_mem_fun<
Placeholder,
const std::string&,
&Placeholder::getPlaceholderId
>
>
>
> currentPlaceholderDatabase;
int main()
{
currentPlaceholderDatabase currentDb;
std::string someString = "something";
volatile auto result = currentDb.get<IndexByPlaceholderId>().find( someString );
if( result == currentDb.get<IndexByPlaceholderId>().end() )
{
std::cout << "NOT FOUNDn";
}
else
{
std::cout << "FOUND!!n";
}
}

本质上,我使用find((搜索一个元素,然后使用运算符==测试是否找到了该元素。我正在做的搜索是使用索引标记,正如boost文档中所解释的那样。如果需要我为这个容器生成一个运算符==,那么有人能演示如何做到这一点吗?因为我在文档中找不到明确的示例?

我得到的错误是:

57:14: error: no match for 'operator==' (operand types are 'volatile boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<Placeholder, std::allocator<Placeholder> > > >' and 'boost::multi_index::detail::ordered_index<boost::multi_index::const_mem_fun<Placeholder, const std::basic_string<char>&, &Placeholder::getPlaceholderId>, std::less<const std::basic_string<char> >, boost::multi_index::detail::nth_layer<3, Placeholder, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<Placeholder> >, boost::multi_index::ordered_non_unique<boost::multi_index::const_mem_fun<Placeholder, const long unsigned int&, &Placeholder::getPlaceholderTime> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<IndexByPlaceholderId>, boost::multi_index::const_mem_fun<Placeholder, const std::basic_string<char>&, &Placeholder::getPlaceholderId> > >, std::allocator<Placeholder> >, boost::mpl::v_item<IndexByPlaceholderId, boost::mpl::vector0<mpl_::na>, 0>, boost::multi_index::detail::ordered_non_unique_tag>::iterator {aka boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<Placeholder, std::allocator<Placeholder> > > >}')

接下来是由于c++模板选项导致的常见的候选长列表。

不幸的是,由于涉及多个级别的模板,错误消息看起来像胡言乱语。Boost.MultiIndex对find()end()使用不同的返回类型,期望隐式转换或函数重载向程序员隐藏这些细节,这使情况变得复杂。幸运的是,解决方案很简单:删除volatile

就像const变量不能用来初始化非const引用一样,volatile变量也不能用来初始化一个非volatile引用。本应实现Boost魔术的各种声明不使用volatile,因此当您将result声明为volatile时,它被排除在外。

在这种情况下,移除volatile不会造成任何伤害。您的result变量没有与其他进程共享,因此volatile除了可能降低代码速度之外,什么也没做。如果你认为你有理由使用volatile,你可能想阅读为什么volatile存在?特别地,volatile并不阻止const。即使它们一开始看起来不兼容,变量也可以是const(不能被当前代码修改(和volatile(可以被程序外部的东西修改(。

最新更新