У меня есть структура для хранения функции обратного вызова как это:
template<class T>
struct CommandGlobal : CommandBase
{
typedef boost::function<T ()> Command;
Command comm;
virtual T Execute() const
{
if(comm)
return comm();
return NULL;
}
};
Кажется, что это должно хорошо работать кроме тех случаев, когда T является пустым, потому что Выполнить функция хочет возвратить значение..
Что лучшее решение к этой проблеме?
Спасибо!
Этот ответ основан на забавном факте : в функции, возвращающей void
, вы можете вернуть любое выражение, тип которого является void.
Итак, простое решение:
virtual T Execute() const
{
if (comm)
return comm();
else
return static_cast<T>(NULL);
}
Когда T = void
, последний оператор return эквивалентен return;
.
Однако я считаю, что это плохой дизайн. Имеет ли значение NULL
для каждые T
? Я так не думаю. Я бы выдал исключение:
virtual T Execute() const
{
if (comm)
return comm();
else
throw std::runtime_error("No function!")
}
Однако это делается автоматически с помощью Boost , поэтому ваш код становится намного чище:
virtual T Execute() const
{
return comm();
}
Затем вы можете добавить дополнительные функции, например:
bool empty(void) const
{
return !comm; // or return comm.empty() if you're the explicit type
}
Итак, пользователь может проверить, можно ли его вызвать, прежде чем вызывать его. Конечно, на данном этапе, если у вашего класса нет дополнительных функций, которые вы упустили ради вопроса, я не вижу причин не использовать просто boost :: function
в первую очередь.
Если это просто оператор return
, это должно сработать:
virtual T Execute() const
{
if(comm)
return comm();
return T();
}
Если есть еще кое-что, специализируйте шаблон для void
.