C ++中lambda函数中的继承参数

时间:2014-03-29 16:54:17

标签: c++ inheritance lambda

我的lamba表达式出现了一些问题:我有一个拥有函数指针的类。

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

我有一个基类:

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

从这一点开始,我得到了很多其他execFunc s不同的类。因此我想使用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
    }
 }

但不幸的是,由于无法从void (*)(Derived*)投射到void (*)(Base*),因此无效。除了在每个lambda函数中将Base*转换为Derived*之外,还有任何建议吗?

期待你的回答, Albjenow

2 个答案:

答案 0 :(得分:0)

不会这样做吗?

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

毕竟你必须尊重execFunc指针的原始签名。

答案 1 :(得分: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的风险。