C ++, Функторы, конкретная задача / сценарий, отображение пользовательского ввода в функции - PullRequest
3 голосов
/ 07 июля 2011

Я уже знаю основы функторов, как они создаются и так далее.Теперь у меня есть конкретный код, который, вероятно, выиграет от преобразования в функторы:

Речь идет о консольном вводе.Если пользователь вводит текст и нажимает клавишу ввода, он пытается выполнить введенный текст как команду.В настоящее время доступные команды хранятся в std::map<std::string, (void*)(std::string)>, где map.first - это имя команды, а map.second - указатель на функцию, содержащую код для этой команды.

Если я теперь преобразую это вфункторы, что было бы лучшим способом сделать это?Я просто заменил бы указатель функции фактическими объектами функтора?Или удалите карту и просто вызовите функтор с командной строкой (commandFunctor("command"))?Если второе: как лучше будет выглядеть такой функтор?Должен ли я тогда создавать только ОДИН класс функторов и в его operator () поместить команду if-else-if-else ... для проверки команд и сохранения в ней кода?

Или я должен создать новый функторкласс для каждой команды и вызовите функтор, соответствующий этой команде?

Итак, вкратце: пользователь вводит команду.Команда ищется.Если команда существует, выполните ее код.Как сделать это наиболее эффективно с помощью функторов?

Ответы [ 3 ]

3 голосов
/ 07 июля 2011

Я бы предложил использовать std::map<std::string, boost::function<void(std::string)> >. Или, если у вас есть доступ к стандартной библиотеке C ++ 0x, вы можете использовать std::function вместо boost::function.

A boost/std::function - это вызываемый объект, который может хранить что угодно , которое можно вызвать с указанным вами типом функции. Таким образом, пользователь может дать вам указатель на функцию, функтор типа, который он создает, или даже объект boost/std::bind, который выполняет компоновку функции.

3 голосов
/ 07 июля 2011

Я бы придерживался общей формы того, что у вас есть, но для хранения команд используйте std::map<std::string, std::tr1::function> (я использую std :: tr1 :: function, но вы можете использовать любой подходящий класс функторов)

0 голосов
/ 07 июля 2011

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

Вам все еще понадобится карта, но, как вы заметили, вы определенно можете заменить указатель функции на функтор, и в зависимости от вашего компилятора / версии / и т. Д. Вы можете использовать std :: tr1 :: function или boost или что еще у вас может быть.

...