Я хотел бы инкапсулировать назначение функторов функции std :: в метод. Вместо передачи std :: function или указателя на std :: function я должен передать функторы, которые наследуются от общего слота абстрактного класса (т. Е. Эти слоты предоставляют дополнительную функциональность).назначить абстрактные функции std :: function - почему std :: ref решение?
Я наткнулся на эту проблему в другой форме here. Например. там, мотивация использования указателей общих слотов вместо std: функции - управление функционалом жизни.
Следующий код иллюстрирует проблему. См. Метод assignFunctorPtr (...).
#include <iostream>
#include <functional>
template<class FunSig>
class Slot;
template<class R>
class Slot<R()>
{
public:
typedef R Ret_type;
public:
virtual ~Slot() {}
virtual Ret_type operator()() = 0;
};
template<class R, class A1>
class Slot<R(A1)>
{
public:
typedef R Ret_type;
typedef A1 Arg1_type;
public:
virtual ~Slot() {}
virtual Ret_type operator()(Arg1_type) = 0;
};
class TestSlot: public Slot<void (float &)>
{
public:
void operator()(float& f)
{ std::cout << f ;}
};
template<class FunSig>
class TestSignal
{
public:
typedef Slot<FunSig> Slot_type;
std::function<FunSig> f;
void assignFunctorPtr(Slot_type* slot_ptr)
{
//f = std::ref(*slot_ptr); // A -> works!
f = *slot_ptr; // B -> compiler error!
}
};
int main()
{
TestSlot* slot = new TestSlot;
TestSignal<void (float &)>* signal = new TestSignal<void (float &)>;
signal->assignFunctorPtr(slot);
}
Этот код ломается, если версия B используется в assignFunctorPtr (...).
Error: "error: cannot allocate an object of abstract type ‘Slot<void(float&)>’
note: because the following virtual functions are pure within ‘Slot<void(float&)>’"
И он компилируется, если используется версия A в assignFunctorPtr (...).
- Почему он компилируется, если std :: ref используется для обертывания функтора?
- Следовательно, каковы конкретные требования к функции std :: для функтора (см. Также std::function reference)
- Что было бы правильным/лучшим способом решить эту проблему?
- Сохраняется ли использование std :: ref?
Шаблонная версия может быть улучшена путем использования 'SlotType && slot' и выполнения' f = std :: forward (slot); 'в теле, я думаю. Таким образом, вызывающий может выбрать, нужно ли перемещать или копировать в зависимости от того, что он передает, и больше никаких указателей. –
David
Спасибо за этот ответ. Я проверил ваше предложение, чтобы сделать assignFunctorPtr (...) шаблоном участника, и он компилируется отлично! – spinxz