Цель: Наличие функции диспетчеризации, работающей по назначению. Минимальный примерный код должен говорить сам за себя. Я хочу поддерживать задачи: Именованная задача, реализованная в их собственном классе, и более простая задача, указанная с использованием лямбда. В идеале все, что может быть преобразовано в std::function<void (void)>
, должно работать.std :: enable_if и std :: shared_ptr
#include <iostream>
#include <memory>
#include <functional>
// A Base class for my tasks
class BaseTask
{
public:
virtual void blah() = 0;
};
// An important enough tasks that it gets to have its
// own class.
class NamedTask : public BaseTask
{
public:
virtual void blah()
{
std::cout << "Hey !" << std::endl;
}
};
// A wrapper around simpler tasks. (lambda)
class GenericTask : public BaseTask
{
public:
GenericTask(const std::function<void (void)> fct) :
fct_(fct) {}
virtual void blah() override
{
fct_();
}
private:
std::function<void (void)> fct_;
};
void enqueue(std::shared_ptr<BaseTask> t)
{
// store in queue.
// We'll just call it here for the sake of the example
t->blah();
}
template<typename Callable>
//typename std::enable_if<!std::is_base_of<BaseTask, Callable>::value>::type
//typename std::enable_if<!std::is_base_of<std::shared_ptr<BaseTask>, Callable>::value>::type
void enqueue(const Callable &c)
{
auto t = std::make_shared<GenericTask>(c);
t->blah();
}
int main()
{
auto named = std::make_shared<NamedTask>();
enqueue(named); // doesn't compile: tries to call the templated enqueue.
enqueue([]() -> bool { std::cout << "Lamda" << std::endl; });
}
Проблема: Я не удается написать правильный enable_if
шаблон. Прокомментированные строки в примере - это то, что я пробовал.
- Первый не работает, потому что Callable имеет тип
std::shared_ptr<NamedTask>
, который не является дочернимBaseTask
. - Второй тоже не удается, предположительно потому, что
std::shared_ptr<NamedTask>
не происходит отstd::shared_ptr<BaseTask>
.
Я не знал о 'std :: is_convertible'. Это именно то, что я искал. Благодарим вас за предоставление жизнеспособных альтернатив. – Xaqq