2010-12-14 3 views
0

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

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

EDIT: Например, я мог бы иметь:

void func1(); 
void func2(); 

void (*fptr[2])(); 

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

func1, 0 func2, 1

если-то еще означает, что я потоковую линию, и я получаю строку Fname = "func1", и location_in_the_array, 0. Таким образом, я буду иметь блок:

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

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

+1

Что именно вы пытаетесь сделать? Указатели функций не являются постоянными, поэтому, даже если это была хорошая идея, вы не могли просто сохранить адрес в файле в массиве, что требует какой-то кодировки. А поскольку C++ действительно не имеет отражения, вам нужно сделать это с if/else. Но у меня такое чувство, что вам будет лучше с картой. – Robert

+0

Это сильно зависит от формата текстового файла.В принципе, то, что вам нужно сделать, называется «разбор». Для простых форматов гигантский блок 'if' /' else if' может выполнять эту работу, но для чего-либо другого предпочтительны другие методы. Как выглядит ваш текстовый файл? – sbi

+0

Вам нужно подробнее рассказать о том, что вы пытаетесь сделать, или предоставить примерный код. Трудно понять из фразы «привязать функции к местоположениям в массиве на основе файла конфигурации текста» –

ответ

2

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


гр

б

это должно разобрать его и поставить указатели на функции в 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; 
} 
0

Может ли косвенная помощь?

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

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

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

1

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

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

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

+0

Я чувствую себя простодушным, говоря, что я подберу его, а затем отвечу на ответ sbi [потому что он более исчерпывающий]. Если вы почувствуете себя обманутым, я изменюсь, чтобы выбрать ваш ответ. – David

+0

Нет проблем. У него был код ... он более исчерпывающий – Robert

Смежные вопросы