2013-01-06 65 views
0

我是新来的C++模板,所以忍耐着我。C++内联模板策略功能

我想要做的是在我的课堂上通过使用模板化函数实现某种策略模式。我认为这将嵌入战略。

我的理解是,这可以通过函数来​​实现,但我不想引入新的类,我只想在我的类中内联策略函数。

可以说我有一个类Calculator

Calculator.h

#ifndef CALCULATOR_H 
#define CALCULATOR_H 


class Calculator 
{ 
    public: 
     Calculator(); 
     virtual ~Calculator(); 
     typedef void (*Strategy)(int param1, int param2); 

     void add(int param1, int param2); 

     template<class T> 
     void doStrategy(T strategy, int param1, int param2); 
    protected: 
    private: 
}; 

#endif 

Calculator.cpp

Calculator::Calculator() 
{ 
    //ctor 
} 

Calculator::~Calculator() 
{ 
    //dtor 
} 

void 
Calculator::add(int param1, int param2) 
{ 
    std::cout << "Sum " << param1+param2 << std::endl; 
} 

template<class T> 
void 
Calculator::doStrategy(T strategy, int param1, int param2) 
{ 
    strategy(param1,param2); 
} 

的main.cpp

int main() 
{ 
    Calculator calc = Calculator(); 

    calc.doStrategy<Calulator::Strategy>(calc.add,2,3); 
    return 0; 
} 

这种失败

error: no matching function for call to ‘Calculator::doStrategy(<unresolved overloaded function type>, int, int)’| 
note: candidate is:| 
note: template<class T> void Calculator::doStrategy(T, int, int)| 
note: template argument deduction/substitution failed:| 
note: cannot convert ‘calc.Calculator::add’ (type ‘<unresolved overloaded function type>’) to type ‘void (*)(int, int)’| 

==后来编辑==

的main.cpp

typedef void (Calculator::*Strategy)(int, int); 
int main() 
{ 
    Calculator calc = Calculator(); 
    Strategy strategy = &Calculator::add; 

    calc.doStrategy<Strategy>(strategy,2,3); 
    return 0; 
} 

仍未有:

undefined reference to `void Calculator::doStrategy<void (Calculator::*)(int, int)>(void (Calculator::*)(int, int), int, int)' 
+0

看看这个链接,您的最新错误的原因:http://www.parashift.com/c++-faq/separate-template-fn-defn-from-decl html的 – JaredC

回答

5

void add(int param1, int param2)不是一个静态方法,因此它是调用一个对象的实例。

这意味着它不能被强制转换为typedef void (*Strategy)(int param1, int param2)这是需要2个整数,并且没有返回,因为前者add具有隐藏在代码,但现实存在的隐式this的方法。实际上该方法的签名是void (Calculator::*)(int,int)。只需将方法设置为static并且应该没问题。

我建议你阅读如何指针成员函数工作详细here,但因为你是用C++工作我真的建议你采取仿函数的优势。

+0

静是不是一种选择,什么我试图做的是比这更复杂的现实世界的例子,但不能贴在这里。 – farnsworth

+2

然后阅读我张贴找到所有与品特合作,成员函数所需的详细信息的链接,但我一直在说,使用仿函数将减轻多少痛苦,即使你最终将不得不更详细的解决方案。 – Jack

+0

+1函子:http://stackoverflow.com/questions/356950/c-functors-and-their-uses 如果您正在使用C++ 11,你也应该考虑使用lambda表达式。 –

0

我的英语短...只是保持代码...

在calculator.h

// this template function use only for calculator's method 
// and method must have two arguments. 
template<typename Method> 
void doStrategy(Method strategy, int param1, int param2) 
{ 
    // argument strategy MUST BE calculator's member function pointer, 
    // member function pointer need object, not class 
    (this->*strategy)(param1, param2); 
} 

在main.cpp中

Calculator cal; 

cal.doStrategy(&calculator::add, 2, 3); 

..更多...一般

in calculator.h

// this template function do not use only for calculator's method 
// but method must have two arguments. 
template<typename Class, typename Method> 
void doStrategy(Class* pObject, Method strategy, int param1, int param2) 
{ 
    // argument strategy MUST BE Class's member function pointer, 
    // member function pointer need object, not class 
    (pObject->*strategy)(param1, param2); 
} 

in main。cpp

// definition of another member function... 
struct foo 
{ 
    void bar(int param1, param2) 
    { 
     std::cout << "foo::bar " << param1 - param2 << std::endl; 
    } 
}; 

int main() 
{ 
    Calculator cal; 
    foo test; 

    cal.doStrategy(&cal, &calculator::add, 2, 3); 
    cal.doStrategy(&test, &foo::bar, 2, 3); 

    foo* just_for_member_function = NULL; 

    cal.doStrategy(just_for_member_function, &foo::bar, 5, 1); 

    return 0; 
} 

更一般吗?

下一次

嗯...