2008-10-20 33 views
4

我想在整個代碼中使用stl算法for_each而不增加模板。 std :: for_each希望通過值實例化MyFunctor類,但它不能自它的抽象。我創建了一個函子適配器類,它傳遞一個指針,然後在適當的時候將其取消。std中的多態函子:: for_each

我的問題:

請問STL或升壓已經有了這樣的適配器類?我不想重新發明輪子!

struct MyFunctor { 
    virtual ~MyFunctor() {} 
    virtual void operator()(int a) = 0; 
} 

namespace { 
    template<typename FunctorType, typename OperandType> struct 
FunctorAdapter 
    { 
     FunctorAdapter(FunctorType* functor) : mFunctor(functor) {} 
     void operator()(OperandType& subject) 
     { 
      (*mFunctor)(subject); 
     } 

     FunctorType* mFunctor; 
    }; } 

void applyToAll(MyFunctor &f) { 
    FunctorHelper<MyFunctor, int> tmp(&f); 
    std::for_each(myvector.begin(), myvector.end(), tmp); } 

乾杯,

戴夫

回答

4

TR1 ::裁判可以幫助你在這裏---它的意思是一個參考的包裝,這樣就可以通過引用傳遞正常對象的函數對象(甚至是抽象的)參照標準算法綁定或。

// requires TR1 support from your compiler/standard library implementation 
#include <functional> 

void applyToAll(MyFunctor &f) { 
    std::for_each(
     myvector.begin(), 
     myvector.end(), 
     std::tr1::ref(f) 
    ); 
} 

但是請注意,編譯器不支持decltype MAY 拒絕經過參考,以抽象類型......所以這段代碼可能無法編譯,直到你的C++ 0x的支持。

5

你可以從functional使用功能適配器(和它們的墊片)。

#include <functional> 

using namespace std; 
for_each(vec.begin(), vec.end(), :mem_fun_ptr(&MyClass::f)); 

如果容器包含指針到對象,請使用mem_fun_ptr,否則使用mem_fun。在這些旁邊,有用於成員函數的包裝器,其中包含1個參數:mem_fun1_ptrmem_fun1

@Evan:的確,您可以使用每個對象的相同參數調用成員函數。所述mem_fun1包裝的第一個參數是this指針,第二個是成員函數參數:

for_each(vec.begin(), vec.end(), bind2nd(mem_fun_ptr(&MyClass::f), 1)); 

隨着越來越多的參數,它變得更加可讀自己創建一個循環,或創建具有const成員的自定義函子表示參數的變量。

+0

好的答案,我不清楚他的例子,但如果矢量包含整數,他不需要綁定一個「這個指針」,該mem_fun? – 2008-10-20 17:29:21

+0

不,因爲這個指針將作爲for_each的參數傳遞。成員函數指針將處理虛擬查找。 – coppro 2008-10-20 19:09:36

0

什麼忘了仿函數指針的所有包裝,而是使用 bind(functor_pointer,mem_fun1(&MyFunctor::operator()); 爲仿函數?這樣,您不必擔心以任何形式或形式管理副本。

0

聽起來像是你可以從Boost::Function受益。

如果我沒有記錯的話,它也是一個只有頭文件的庫,所以很容易讓它順利進行。

0

大廈@ xtofl的回答,因爲數組包含INT的,而不是「本」的指針,我認爲正確的咒術

class MyClass 
{ 
    virtual void process(int number) = 0; 
}; 
MyClass *instance = ...; 

for_each(vec.begin(), vec.end(), binder1st(instance, mem_fun_ptr(&MyClass::process)); 

與@ xtofl的代碼唯一的區別是binder1st而非binder2nd。 binder2nd允許你將相同的數字傳遞給各種「this」指針。 binder1st允許您將各種數字傳遞給一個「this」指針。

相關問題