3 回答

TA貢獻1887條經驗 獲得超5個贊
您可以通過多種選擇來實現C ++中的委托。這是我想到的那些。
選項1:函子:
可以通過實現來創建功能對象 operator()
struct Functor
{
// Normal class/struct members
int operator()(double d) // Arbitrary return types and parameter list
{
return (int) d + 1;
}
};
// Use:
Functor f;
int i = f(3.14);
選項2:lambda表達式(僅C ++ 11)
// Syntax is roughly: [capture](parameter list) -> return type {block}
// Some shortcuts exist
auto func = [](int i) -> double { return 2*i/1.15; };
double d = func(1);
選項3:函數指針
int f(double d) { ... }
typedef int (*MyFuncT) (double d);
MyFuncT fp = &f;
int a = fp(3.14);
選項4:指向成員函數的指針(最快的解決方案)
請參見Fast C ++ Delegate(在The Code Project上)。
struct DelegateList
{
int f1(double d) { }
int f2(double d) { }
};
typedef int (DelegateList::* DelegateType)(double d);
DelegateType d = &DelegateList::f1;
DelegateList list;
int a = (list.*d)(3.14);
選項5:std :: function
(或者boost::function如果您的標準庫不支持它)。它比較慢,但是最靈活。
#include <functional>
std::function<int(double)> f = [can be set to about anything in this answer]
// Usually more useful as a parameter to another functions
選項6:綁定(使用std :: bind)
允許預先設置一些參數,例如方便調用成員函數。
struct MyClass
{
int DoStuff(double d); // actually a DoStuff(MyClass* this, double d)
};
std::function<int(double d)> f = std::bind(&MyClass::DoStuff, this, std::placeholders::_1);
// auto f = std::bind(...); in C++11
選項7:模板
接受與參數列表匹配的任何內容。
template <class FunctionT>
int DoSomething(FunctionT func)
{
return func(3.14);
}

TA貢獻1830條經驗 獲得超3個贊
委托是一個類,它包裝指向對象實例的指針或引用,該對象實例在該對象實例上要被調用的成員方法,并提供觸發該調用的方法。
這是一個例子:
template <class T>
class CCallback
{
public:
typedef void (T::*fn)( int anArg );
CCallback(T& trg, fn op)
: m_rTarget(trg)
, m_Operation(op)
{
}
void Execute( int in )
{
(m_rTarget.*m_Operation)( in );
}
private:
CCallback();
CCallback( const CCallback& );
T& m_rTarget;
fn m_Operation;
};
class A
{
public:
virtual void Fn( int i )
{
}
};
int main( int /*argc*/, char * /*argv*/ )
{
A a;
CCallback<A> cbk( a, &A::Fn );
cbk.Execute( 3 );
}

TA貢獻1836條經驗 獲得超5個贊
對C ++委托實現的需要是對C ++社區的長期困擾。每個C ++程序員都希望擁有它們,因此盡管存在以下事實,他們還是最終使用了它們:
std::function()
使用堆操作(對于嚴重的嵌入式編程是無法實現的)。所有其他實現都在或多或少程度上對可移植性或標準一致性做出了讓步(請通過在此處和在代碼項目上檢查各種委托實現進行驗證)。我還沒有看到一個不使用野生的reinterpret_casts的實現,嵌套類“原型”希望產生與用戶傳遞的函數指針大小相同的函數指針,編譯器的技巧如第一個前向聲明,然后是typedef然后再聲明,這次是從另一個班級或類似的黑幕技術繼承下來的。雖然這對于實現此目標的實現者來說是一項巨大的成就,但對于C ++的發展仍然是一個可悲的見證。
很少有人指出,現在超過3個C ++標準修訂版,未正確處理委托。(或者缺少允許直接實現委托實現的語言功能。)
通過標準定義C ++ 11 lambda函數的方式(每個lambda具有匿名的不同類型),這種情況僅在某些用例中得到了改善。但是對于在(DLL)庫API中使用委托的用例,僅 lambda 仍然不可用。此處的常用技術是先將lambda打包到std :: function中,然后將其傳遞給API。
- 3 回答
- 0 關注
- 686 瀏覽
添加回答
舉報