2013-12-20 56 views
1

我有,我不能綁定此模板成員函數一個奇怪的問題, 所有這些代碼編譯:http://ideone.com/wl5hS8的std ::綁定模板成員函數

這是一個簡單的代碼:我有一個ExecutionList應持有可調用的函數在std::vector。我現在可以通過調用ExecutionList::addFunctor來添加功能。但在那裏,我不能綁定到template<typename T> void Functor::calculate(T * t)。我問我爲什麼,是什麼在這裏失蹤,編譯器不能莫名其妙地推斷我已經寫在

m_calculationList.push_back(std::bind(&T::calculate<Type>, extForce, std::placeholders::_1)); 

* 錯誤:*

error: expected primary-expression before ‘>’ token 
       m_calculationList.push_back(std::bind(T::calculate<Type>, extForce, std::placeholders::_1)); 
                    ^

驗證碼:

#include <functional> 
#include <iostream> 
#include <vector> 

struct MyType{ 
    static int a; 
    int m_a; 
    MyType(){a++; m_a = a;} 

    void print(){ 
     std::cout << "MyType: " << a << std::endl; 
    } 
}; 
int MyType::a=0; 


struct Functor{ 

    static int a; 
    int m_a; 

    Functor(){a++; m_a = a;} 

    // Binding this function does not work 
    template<typename T> 
    void calculate(T * t){} 

    // Binding this function works!!! 
    void calculate2(MyType * t){ 
     std::cout << " Functor: " << m_a <<std::endl; 
     t->print(); 
    } 

}; 

int Functor::a=0; 

// Binding this function works!!! 
template<typename T> 
void foo(T * t){} 

class ExecutionList{ 
    public: 
     typedef MyType Type; 

     template<typename T> 
     void addFunctor(T * extForce){ 
      //m_calculationList.push_back(std::bind(&T::calculate<Type>, extForce, std::placeholders::_1)); /// THIS DOES NOT WORK 
      m_calculationList.push_back(std::bind(&T::calculate2, extForce, std::placeholders::_1)); 
      m_calculationList.push_back(std::bind(&foo<Type>, std::placeholders::_1)); 
     } 


     void calculate(Type * t){ 
      for(auto it = m_calculationList.begin(); it != m_calculationList.end();it++){ 
       (*it)(t); // Apply calculation function! 
      } 
     } 

    private: 
     std::vector< std::function<void (Type *)> > m_calculationList; 
}; 



int main(){ 
    MyType b; 
    ExecutionList list; 
    list.addFunctor(new Functor()); 
    list.addFunctor(new Functor()); 
    list.calculate(&b); 
} 
+0

那意味着我需要一些''typename''字樣?這是否合理,因爲它不是一個類型,而是一個函數指針 – Gabriel

+3

還有另一個消歧器:'模板'。 'std :: bind(&T :: template calculate ,...)'應該工作。此外,*總是*包括你得到的錯誤信息。 「不工作」不起作用。 – Xeo

+0

ahhh damm it,我認爲它是這些愚蠢的東西之一,但從來沒有使用過某種類型的模板,只是有時候如''a.template foo '''如果'foo'不可扣除 – Gabriel

回答

3

看起來你缺少模板關鍵字。如果T是模板參數,T :: calculate是指模板,則需要告訴編譯器計算的是模板,而不是某個靜態變量,您試圖使用小於運算符與其他值進行比較:

T::template calculate<Type> 

我幾年前碰到了完全相同的問題,但今天(POST C++ 11),我可能會用一個lambda這是簡單的解決這個問題:

std::function<void(Type*)> func = [obj](Type*param){obj.calculate(param);}; 

總之,儘量減少數量new用途。尋找更好的方式來管理您的資源。你的代碼似乎泄漏了一些函子。