Использовать boost :: function в качестве аргумента функции? - PullRequest
1 голос
/ 17 октября 2011

Я хочу вызвать функцию foo и позволить ей вести себя по-другому.
(Я использую шаблон стратегии или команды. Они похожи на меня.)

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

Сначала определите foo, чтобы получить boost :: function type

foo(boost::function<someType> execFunction)
{
// do something 
execFunction(args);
// do something
}

Затем я даю foo () разные функции (в качестве аргумента) в зависимости от того, что я хочу.

Будет ли это работать?или Вы бы посоветовали против этого?
Любые комментарии приветствуются.

edit

Незначительный связанный с этим вопрос: иногда execFunction требует 1 аргумент, а иногда - 2 аргумента.

Я мог бы использовать boost :: function для обоих случаев и просто игнорировать 2-й аргумент, когда он не нужен.
Есть ли более чистый способ сделать это?

Ответы [ 2 ]

4 голосов
/ 17 октября 2011

Это работает очень хорошо. Но иногда предпочтительнее работать с functor, чтобы ваши абоненты могли сами выбирать, что лучше для них, и предотвращать небольшие накладные расходы, которые идут с boost::function:

template<typename Func>
void foo(Func f) {
  f(myArgs);
}

Вы также можете добавить перегрузку для конкретного boost::function, чтобы получить объект по ссылке.

template<>
void foo(const boost::function<void (expectedtypes)>& f) {
  f(myArgs);
}

И, возможно, это тоже перегружено для константности.

В случае приема boost::function объектов различной арности, я бы использовал перегрузку. Если вы идете по этому пути, избегайте шаблонной версии, поскольку у вас возникнут проблемы, как только ваши пользователи попытаются работать с функторами (в отличие от boost::function с другой арностью). Эта проблема разрешима, но может стать грязной. Вам нужно было бы отправить вызов чему-то, что обнаруживает арентность фьюнтера и выполняет правильный вызов. Но, как вы сказали, шаблоны - это ваше слабое место, это не рекомендуется.

0 голосов
/ 17 октября 2011

Это обычный шаблон, и он будет работать. Я использовал это в прошлом и, скорее всего, буду использовать его в будущем. Я пытаюсь использовать его только в некоторых конкретных случаях, так как это значительно снижает сцепление, и хотя это хорошо в целом, затрудняет отслеживание потока контроля из кода (т. Е. Если вы злоупотребите им, это будет действительно трудно найти то, что ваша программа предназначена для выполнения, кроме запуска в отладчике). Но для конкретных задач это хорошо.

Если вам не нужно хранить function<> для последующего использования или какое-либо полиморфное поведение во время выполнения на стороне вызываемого, вы также можете рассмотреть возможность использования шаблона функции, чтобы вызывающим абонентам не приходилось преобразовывать в function<> перед выполнением вашей функции.

...