2013-12-20 63 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用途。寻找更好的方式来管理您的资源。你的代码似乎泄漏了一些函子。