Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос по boost::multi_index 
:(
    Опции темы
Superklug
Дата 31.5.2010, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Доброго времени суток!

Необходимо написать класс-контейнер который позволяет получать доступ как по ключу (как std::map), так и по индексу (как std::vector).
Начал разбираться с boost::multi_index... Написал примерно следующее:
Код

    struct ObjectProperty
    {
        StringType name;
        Value value;
        ObjectProperty()
        {
        };
        ObjectProperty( const StringType& name_, const Value& value_ ) :
            name(name_),
            value(value_)
        {
        };
    };

    

    class Object
    {
    private:
        typedef multi_index_container<
            ObjectProperty,
            indexed_by<
                ordered_unique< member< ObjectProperty, StringType, &ObjectProperty::name > >,
                random_access<>
            >
        > ObjectPropertySet;
        
        ObjectPropertySet _propertySet;

    public:
        int size() const;

        const Value& operator[]( StringType propertyName ) const;
        Value& operator[]( StringType propertyName );

        const ObjectProperty& operator[]( const int index ) const;
        ObjectProperty& operator[]( const int index );

        void addProperty( const ObjectProperty& op );
        
        void removeProperty( StringType propertyName );
        void clear();
        bool empty() const; 
    };


Однако возникли сложности с реализацией методов, которые возвращают ссылки на элементы контейнера (не константные).

Т.е. такой код работает:
Код

    inline const ObjectProperty& Object::operator[]( const int index ) const
    {
        return _propertySet.get<1>()[index];
    }


А вот такой нет:
Код

    inline ObjectProperty& Object::operator[]( const int index )
    {
        return _propertySet.get<1>()[index];
    }


Вычитал, что изменять значения multi_index позволяют методы replace и modify, но в моем случае они не помогут(

Подскажите как быть в этой ситуации? Отказаться от multi_index и делать средствами stl или есть все таки способ?

Заранее спасибо!

PM MAIL   Вверх
xvr
Дата 31.5.2010, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Superklug @  31.5.2010,  12:41 Найти цитируемый пост)
есть все таки способ
Нету, даже средствами stl. Возврат не-константной ссылки подразумевает возможность модификации объекта, по этой ссылке. Если этот объект входит в один или более индексов multi_index, то после такой модификации все затронутые индексы должны быть автоматически пересчитанны, что практически нереализуемо в рамках стандартных контейнеров stl


PM MAIL   Вверх
Superklug
Дата 31.5.2010, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Ну с помощью stl можно хранить множество (std::set) элементов и вектор (std::vector) указателей на эти элементы...
Просто это будет не так красиво как с использованием multi_index.

Я думаю из приведенного кода задача ясна.. Есть класс Value (фактически Variant) который может хранить объекты определенных типов (включая Object). Как бы вы реализовали класс Object?
PM MAIL   Вверх
xvr
Дата 31.5.2010, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Superklug @  31.5.2010,  16:50 Найти цитируемый пост)
Как бы вы реализовали класс Object? 
Отделить ключ (имя+индекс) от собственно содержимого. Ключ хранить в multi_index_container, данные хранить отдельно в map или vector


PM MAIL   Вверх
Superklug
Дата 1.6.2010, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Цитата(xvr @  31.5.2010,  18:34 Найти цитируемый пост)
Отделить ключ (имя+индекс) от собственно содержимого. Ключ хранить в multi_index_container, данные хранить отдельно в map или vector


Не получается(
Код

using namespace boost::multi_index;

    class Object
    {
    private:
        typedef std::vector<Value> DataSet;
        
        struct Property
        {
            StringType name;
            DataSet::iterator value;
            Property( const StringType& name_, DataSet::iterator value_ ) :
                name(name_),
                value(value_)
            {
            };
        };

        typedef multi_index_container<
            Property,
            indexed_by<
                ordered_unique< member< Property, StringType, &Property::name > >,
                random_access<>
            >
        > IndexSet;

        DataSet _dataSet;
        IndexSet _indexSet;

    public:
        int size() const;

        const Value& operator[]( const StringType& propertyName ) const;
        Value& operator[]( const StringType& propertyName );

        const StringType& propertyName( const int index ) const;

        bool addProperty( const StringType& name_, const Value& value_ );
        
        void removeProperty( const StringType& propertyName );
        void clear();
        bool empty() const; 
    };


Если пытаюсь по имени получить из multi_index итератор, то он возвращает его как const iterator. В итоге пришел к тому с чего начал... Может я не так вас понял? Можете набросать небольшой пример?

Спасибо!

PM MAIL   Вверх
xvr
Дата 1.6.2010, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Я имел в виду хранить в multi_index_container вместе с ключем уникальный идентификатор (целое число), и по нему извлекать данные из другого контейнера. Сам идентификатор создается один раз (при создании элемента) и в дальнейшем не меняется.

Что использовать в качестве 2го контейнера зависит от того, насколько часто будут удаляться элементы. Если не часто (или вообще не будут), то использовать vector (в этом случае идентификатором будет индекс). Иначе использовать map, у которого в качестве ключа используется этот же идентификатор (на этот раз просто значение счетчика, который увеличивается на 1 при каждом создании элемента)

PM MAIL   Вверх
Superklug
Дата 1.6.2010, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Спасибо!
Теперь все понятно. Жалко только, что решение вышло не такое элегантное, как виделось в начале)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0471 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.