2014-03-29 102 views
2

我的lamba表達式有一些問題:我有一個擁有函數指針的類。在C++ lambda函數中繼承參數

class SomeClass 
{ 
    void (*execFunc)(Base*); 
} 

而且我有一個基類:

class Base 
{ 
    SomeClass* someClass; 
    void doSomething() { someClass->execFunc(this); } 
} 

從這一個我得到很多其他類,它們的execFunc旨意是不同的。因此我想使用lambda表達式; e.g:

class Derived final : public Base 
{ 
    int someDerivedAttrib; 

    static List<SomeClass*> someClasses = createSomeClasses(); // holds all possible 
                    // SomeClasses for this 
                    // derived class 
    static List<SomeClass*> createSomeClasses() 
    { 
     List<SomeClass*> scs; 
     SomeClass* sc = new SomeClass(); 
     sc->execFunc = [] (Derived* derived) { derived->someDerivedAttrib = 10; }; 
     scs << sc; 
     return scs 
    } 
} 

但unfornately這是不行的,因爲演員是void (*)(Derived*)void (*)(Base*)是不可能的。任何建議,除了在每個lambda函數中使用Base*Derived*強制轉換?

期待你們的答案, Albjenow

+0

出於好奇,這有什麼實際的使用場景? –

回答

0

怎麼樣,而不是SomeClass是一個普通的類,使它成爲類模板的基類,處理具有適當的函子類型,以及向下轉換爲正確的類型?
它應該是這樣的:

class SomeClass 
{ 
    virtual void callFunc(Base*) = 0; 
} 

template<typename T> 
class SomeDerivedClass : public SomeClass 
{ 
    static_assert(std::is_base_of<Base, T>::value, "SomeDerivedClass: unexpected base class"); 
    virtual void callFunc(Base* b) override 
    { 
     execFunc(static_cast<T*>(b)); 
    } 
    void (*execFunc)(T*); 
} 

Base就變成了:

class Base 
{ 
    SomeClass* someClass; 
    void doSomething() { someClass->callFunc(this); } 
} 

然後,在你Derived定義:

class Derived final : public Base 
{ 
    int someDerivedAttrib; 

    typedef SomeDerivedClass<Derived> tSomeClass; 
    static List<tSomeClass*> someClasses = createSomeClasses(); // holds all possible 
                    // SomeClasses for this 
                    // derived class 
    static List<tSomeClass*> createSomeClasses() 
    { 
     List<tSomeClass*> scs; 
     tSomeClass* sc = new tSomeClass(); 
     sc->execFunc = [] (Derived* derived) { derived->someDerivedAttrib = 10; }; 
     scs << sc; 
     return scs 
    } 
} 

然而,這種運行調用SomeDerivedClass::call與風險錯誤的具體類。

+0

但我需要從基類中調用'SomeClass :: execFunc',它包含指向它的指針。 – Albjenow

+0

好吧,我明白了..將編輯 –

+0

正是我剛想到的,gj,豎起大拇指。 – Albjenow

0

這是不是做的伎倆?

sc->execFunc = [] (Base* base) { static_cast<Derived*>(base)->someDerivedAttrib = 10; 

畢竟你必須尊重execFunc指針的原始簽名。

+1

從最初的問題:'除了在每個lambda函數中將一個強制轉換形式Base *導出*之外,還有什麼建議? –

+0

當然會,但如前所述,我正在尋找另一種策略,因爲我是一個非常懶惰的程序員。否則,我也可以使用一個擴展的if-else語句來評估當前的SomeClass。 – Albjenow