Регистрация обратных вызовов из текстового файла конфигурации - PullRequest
0 голосов
/ 15 декабря 2010

У меня общая проблема, когда у меня есть массив указателей на функции.Задача состоит в том, чтобы связать функции с местами в массиве на основе текстового файла конфигурации.Есть ли лучший способ сделать это, чем гигантский блок if-else-else -...- else?

Легче ли реализовать функторы и привязать местоположения к экземплярам типа?

РЕДАКТИРОВАТЬ: Например, я мог бы иметь:

void func1();
void func2();

void (*fptr[2])();

Я хочу иметь файл конфигурации ввода, который говорит мне, что func1 идет в fptr [0], а func2 идет в fptr [1].

func1, 0 func2, 1

if-else означает, что я передаю строку и получаю строку fname = "func1" и location_in_the_array, 0. Итак, у меня будет блок:

if (fname.compare("func1")) 
{
  fptr[location_in_the_array] = func1;
}
else if (...) {}

Хорошая идея - карта, и она пару раз всплывала у меня в голове, но я космический курсант и забыл ее, прежде чем я спросил.

Ответы [ 3 ]

2 голосов
/ 15 декабря 2010

Предполагая формат файла, такой как

а
с
а
б

это должно разобрать его и поместить указатели функций в std::vector соответственно:

// Beware, untested code ahead!

typedef void (*func_t)();
typedef std::map<std::string, func_t>   func_map_t;
typedef func_map_t::value_type          func_map_entry_t;

void f1() {}
void f2() {}
void f3() {}

const func_map_entry_t func_map_entries[] = { func_map_entry_t("a", &f1)
                                            , func_map_entry_t("b", &f2)
                                            , func_map_entry_t("c", &f3) };

const func_map_t func_map( func_map_entries
                         , func_map_entries + sizeof(func_map_entries)
                                            / sizeof(func_map_entries[0]));

func_t read_line(std::istream& is)
{
    std::string token;
    if(!(is >> token)) throw "you need better error handling!";
    func_map_t::const_iterator found = func_map.find(token);
    if(found == func_map.end()) throw "you need better error handling!";
    return found->second;
}

std::vector<func_t> read_config(std::istream& is)
{
    std::vector<func_t> result;
    std::string line;
    while(std::getline(is,line))
    {
        std::istringstream iss(line);
        func_t func = read_line(iss);
        if(!func) throw "you need better error handling!";
        result.push_back(func);
    }
    if(is.eof()) throw "you need better error handling!";
    return result;
}
1 голос
/ 15 декабря 2010

Если вы ответите «Использовать карту», ​​я ее выберу.

Используйте карту.

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

0 голосов
/ 15 декабря 2010

Поможет ли косвенное обращение?

Например, возьмите свои указатели на функции и во время компиляции присвойте их хеш-таблице по имени, возможно, по идентификатору имени функции.

Затем во время выполнения загрузите текстовый файл, представляющий собой список имен.

Создайте массив, выполнив поиск по идентификатору, найдите его указатель на функцию в хэш-таблице и заполните массив.

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