我想將函子的賦值封裝到std :: function中。我不得不傳遞std :: function或指向std :: function的指針,而必須傳遞從通用抽象類Slot繼承的函子(即這些插槽提供附加功能)。將抽象函數賦值給std :: function - 爲什麼是std :: ref解決方案?
我偶然發現了不同形狀的這個問題here。例如。在那裏,使用通用槽的指針而不是std:functions的動機是函子的生命週期管理。
下面的代碼說明了這個問題。請參閱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);
}
如果在assignFunctorPtr(...)中使用版本B,則此代碼會中斷。
Error: "error: cannot allocate an object of abstract type ‘Slot<void(float&)>’
note: because the following virtual functions are pure within ‘Slot<void(float&)>’"
並將其編譯如果使用在assignFunctorPtr(...)A版本。
- 如果使用std :: ref來包裝函子,它爲什麼會編譯?
- 因此,函子的std :: function的具體要求是什麼(請參閱std::function reference)
- 什麼是解決此問題的正確/最佳方法?
- 保存使用std :: ref嗎?
模板版本可以通過'SlotType && slot'和'f = std :: forward(slot);'在我的身上得到改進。通過這種方式,調用者可以根據他傳入的內容來選擇是移動還是複製,也不需要更多指針。 –
David
2013-04-30 12:34:38
感謝您的回答。我檢查了你的建議,使assignFunctorPtr(...)成員模板,它編譯好! – spinxz 2013-04-30 12:35:31