Как проверить, что boost multi_index вернул элемент, используя find () и end () - PullRequest
0 голосов
/ 14 марта 2020

Я не работал с 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 . Если требуется, чтобы я сгенерировал оператор == для этого контейнера, может кто-нибудь продемонстрировать, как это сделать, поскольку я не могу найти четкий пример в документации?

Я получаю ошибку:

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 ++.

1 Ответ

2 голосов
/ 15 марта 2020

К сожалению, сообщение об ошибке имеет вид gibberi sh из-за множества уровней шаблонизации. Это усложняется тем, что Boost.MultiIndex использует различные типы возвращаемых значений для find() и end(), ожидая либо неявных преобразований, либо перегрузок функций, чтобы скрыть эту деталь от программиста. К счастью, решение простое: remove volatile.

Так же, как переменная const, не может использоваться для инициализации не const ссылки, переменная volatile не может использоваться для инициализации не volatile ссылки. В различных объявлениях, которые должны заставить Волшебников Усиления c произойти, не используется volatile, поэтому, когда вы объявили result равным volatile, оно было оставлено на морозе.

Там не должно быть никакого вреда, вызванного удалением volatile в этом случае. Ваша переменная result не используется совместно с другими процессами, поэтому volatile не выполняет ничего, кроме возможного замедления вашего кода. Если вы думали, что у вас есть причина для использования volatile, вы можете прочитать Почему существует энергозависимый? В частности, volatile не препятствует const. Несмотря на то, что на первый взгляд они выглядят несовместимыми, переменная может быть как const (не может быть изменена текущим кодом ), так и volatile (может быть изменена чем-то внешним для программы ).

...