C ++ контейнер структур, необходимый для операций поиска двойного доступа - PullRequest
0 голосов
/ 19 апреля 2011

У меня есть структура, которую мне нужно поместить в контейнер в C ++.вот структура:

struct PDCUTestMessage
{
string name;
unsigned char id;
int numberOfParameters;
string param1Name;
string param2Name;
string param3Name;
string param4Name;
string param5Name;
boost::function<void(vector<unsigned char>)> process;
PDCUTestMessage();
PDCUTestMessage(string_name, unsigned char _id, int _numberOfParameters, boost::function<void(vector<unsigned char>)> _process): name(_name), id(_id), numberOfParameters(_numberOfParameters), process(_process){}
};

Мне понадобится около 65 таких структур, поэтому я собираюсь поместить их в контейнер (я думаю, список, вектор или карта).Мне нужно иметь возможность получить доступ к указателю функции (процесс) данного PDCUTestMessage через два разных значения поиска: имя и идентификатор.Я заметил, что карта допускает только одно значение и один ключ.Есть ли какой-нибудь контейнер, который позволил бы мне быстро искать PDCUTestMessage, используя в качестве ключа имя или идентификатор?И как мне написать поиск и получить доступ к функции, на которую указывает указатель?

Надеюсь, это имеет смысл.Дайте мне знать, если вам нужны дальнейшие разъяснения.

Спасибо!

Ответы [ 3 ]

1 голос
/ 19 апреля 2011

Поскольку вы уже используете boost, здесь может быть полезна библиотека контейнеров boost.multi-index .В частности, рассмотрим примеры из учебного раздела Multiple sort .

0 голосов
/ 19 апреля 2011

Как уже упоминалось, Boost.MultiIndex - это один из способов решения такой проблемы.Это очень мощный и быстрый , но в большинстве случаев это просто означает медленную компиляцию и сложный код , при этом не получая много других преимуществ.

65 элементов не так уж много икак отметил Марк Рэнсом, линейный поиск может работать достаточно хорошо для того, что вы делаете.Это вам нужно измерить.

Другой способ сделать что-то - это иметь std :: vector для хранения сообщений (65 сообщений), а затем вы можете иметь два отдельных контейнера, которые вы используете для поиска: first это id-to-index, а second это имя-to-index.Индекс - это позиция сообщения в векторе.Примерно так:

class YourContainerClass
{
public:
    bool lookupById(unsigned char id, PDCUTestMessage& message)
    {
        std::map<unsigned char, int>::iterator it = idToIndexMap.find(id);
        if (it == idToIndexMap.end())
            return false;
        message = messages[*it];
        return true;
    }

    bool lookupByName(const std::string& name, PDCUTestMessage& message)
    {
        std::map<std::string, int>::iterator it = nameToIndexMap.find(id);
        if (it == nameToIndexMap.end())
            return false;
        message = messages[*it];
        return true;
    }

private:
    std::vector<PDCUTestMessage> messages;
    std::map<unsigned char, int> idToIndexMap;
    std::map<std::string, int> nameToIndexMap;
};

Чтобы управлять внутренними контейнерами, ваша вставка должна выполнить команду push_back в векторе сообщений и одновременно вставить в две карты соответствующие вещи, чтобы найти индекс в вектореот идентификатора и имени.

Это всего лишь один из способов, как будет выглядеть API.Вы также можете обернуть сообщения в boost :: shared_ptr , чтобы получить немного другой API.Это несколько выходит за рамки вашего вопроса, потому что я также не знаю, как вы намереваетесь использовать сообщения и их время жизни.

Я бы сказал, даже если Boost.MultiIndex - очень крутой контейнер, он не долженбудь первым вариантом.Есть много способов сделать это, и это сводится к конкретным проблемам, которые наиболее важны.

Надеюсь, вы найдете то, что имеет для вас наибольшее значение.

0 голосов
/ 19 апреля 2011

В вашем контейнере всего 65 предметов, простой линейный поиск может быть достаточно быстрым для ваших нужд.Используйте имя в качестве ключа для вашей карты (или набора) и используйте std :: find, когда вам нужно выполнить поиск по id.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...