2013-01-06 62 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; 
} 

更一般嗎?

下一次

嗯...