2011-03-02 368 views
0

我正在测试一个属性系统,我想确保根类可以保存函数指针,这个函数指针指向的是派生类。因此,我有一些工作。大多数派生类正在工作(RC2),但当前中间类(RC1)将有编译器错误。我想能够实例化RC1和RC2。编译器错误创建时,我将与RC得到的是(对于RC1<RC1> rc1test;行)默认的模板参数

错误C2955:“RC1”:使用类模板需要模板参数列表

错误C3203:“RC1” :非专业化的类模板不能作为模板参数“PropertyOwner”模板参数,预计一个真正的类型

我试图做RC1<> rc1test;但这并没有帮助。这里是来源,有没有人有任何建议?

#include <iostream> 
#include <map> 
#include <string> 
using namespace std; 

template<class T, class BaseClass> 
class RBase : public BaseClass 
{ 
public: 
    typedef int (T::*GetFP)(void) const; 

protected: 
    std::map<const char*, GetFP> mGetFPs; 

}; 

class CBase 
{ 

}; 

template<class PropertyOwner> 
class RC1; 

template<class PropertyOwner=RC1> 
class RC1 : public RBase<PropertyOwner, CBase> 
{ 
public: 
    int int1(void) const 
    { 
    return 1; 
    } 

    RC1() 
    { 
    mGetFPs.insert(pair<const char*, GetFP>("RC1I1I", &PropertyOwner::int1)); 
    }; 

    virtual void inspection(void) 
    { 
    int test = 0; 
    } 
}; 

class RC2 : public RC1<RC2> 
{ 
public: 
    int int2(void) const 
    { 
    return 2; 
    } 

    RC2() 
    { 
    mGetFPs.insert(pair<const char*, GetFP>("RC2I2I", &RC2::int2)); 
    }; 

    virtual void inspection(void) 
    { 
    int test = 0; 
    } 
}; 

int main(void) 
{ 
    RC1<RC1> rc1test; 

    RC2 rc2test; 
    rc2test.inspection(); 

    return(0); 
} 
+0

要让Stackoverflow将文本视为代码,请在每行之前添加四个空格。 – fbrereto 2011-03-02 19:19:55

+0

要在stackoverflow上格式化代码,只需缩进四个空格。或者粘贴一些代码,突出显示它,然后按下'{}'按钮。 – aschepler 2011-03-02 19:19:59

+0

完成:-)要查看未格式化的版本,请单击编辑。 – TonyK 2011-03-03 15:34:25

回答

1

如果你可以使用boost,那么你可以使用boost :: function和boost :: bind来获得你想要的指针。

template <typename BC> 
    class RBase : public BC 
    { 
    public: 
     typedef int FunctionSignature (void) const; 
     typedef boost::function<FunctionSignature> CallbackFunction; 
    protected: 
     std::map<const char*, CallbackFunction> mGetFPs; 
    }; 

    class CBase 
    { 
    }; 

    class RC1 : public RBase<CBase> 
    { 
    public: 
     RC1() 
     { 
      mGetFPs.insert (std::make_pair ("RC1I1I", 
               boost::bind (&RC1::int1, this))); 
     } 
     int int1(void) const { return 1; } 
    }; 


    class RC2 : public RC1 
    { 
    public: 
     RC2() 
     { 
      mGetFPs.insert (std::make_pair ("RC2I2I", 
               boost::bind (&RC2::int2, this))); 
     } 
     int int2(void) const { return 2; } 
    }; 

其实,你可以分配具有升压::功能合适签名的任何功能,甚至使用boost ::绑定,以适应有额外的参数(见下文)的功能。

class RC3 : public RC1 
    { 
    public: 
     RC3() 
     { 
      mGetFPs.insert (std::make_pair ("RC3I3I", 
               boost::bind (&RC3::intN, this, 3))); 
     } 
     int intN(int n) const { return n; } 
    }; 
+0

为什么在“boost :: bind(&RC3 :: intN,this,3)”中有3个?我以为3是为了多少参数? – jack 2011-03-03 19:42:45

+0

实际上,绑定中的“3”是当mGetFPS [“RC3I3I”]。second()被调用时将作为参数传递给intN的值。这是一个例子,你如何实际使用boost :: bind来修改一个函数的额外参数在它的签名中。我猜“3”的价值是不幸的。 – vicki 2011-03-03 20:03:42

1
template<class PropertyOwner=RC1> 
class RC1 /*...*/; 

如果没有为模板类型参数PropertyOwner默认参数,它需要一个类型。 RC1而不是类型。它是一个类模板。

+0

对于代码的上下文,您有什么建议可能是一种很好的类型?我认为它会将RC1视为一种类型。 – jack 2011-03-02 19:47:36