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

How to test if boost multi_index has returned an element using find() and end()

我已经有几年没有使用 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 FOUND\n";
    }
    else
    {
        std::cout << "FOUND!!\n";
    }
}

本质上,我正在使用 find() 搜索元素,然后使用 operator== 测试是否找到该元素。我正在进行的搜索是使用索引标记,如 boost documentation 中所述。如果要求我为这个容器生成一个 operator== ,有人可以演示如何这样做吗,因为我在文档中找不到明确的例子?

我得到的错误是:

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() 使用不同的 return 类型的方式使情况变得复杂,期望隐式转换或函数重载向程序员隐藏该细节。幸运的是,解决方案很简单:删除volatile.

就像 const 变量不能用于初始化非 const 引用一样,volatile 变量不能用于初始化非 volatile 引用.应该使 Boost 魔法发生的各种声明不使用 volatile,因此当您将 result 声明为 volatile 时,它被冷落了。

在这种情况下,删除 volatile 应该不会造成任何伤害。您的 result 变量未与其他进程共享,因此 volatile 除了可能减慢您的代码速度外,什么也做不了。如果您认为您有使用 volatile 的理由,您可能想阅读 Why does volatile exist? 特别是,volatile 不会阻止 const。尽管它们一开始看起来不兼容,但一个变量可以是 const(不能被当前代码修改 )和 volatile(可以被修改 通过程序外部的东西).