I have a strange problem that I cannot bind this template member function, all this code compiles: http://ideone.com/wl5hS8
It's a simple code: I have a ExecutionList
which should hold callable functions in a std::vector
. I can now add functions by calling ExecutionList::addFunctor
. But there, I cannot bind to template<typename T> void Functor::calculate(T * t)
. I am asking me why, what is missing here, the compiler cannot somehow deduce what I have written in
m_calculationList.push_back( std::bind(&T::calculate<Type>, extForce, std::placeholders::_1 ) );
*Error: *
error: expected primary-expression before ‘>’ token
m_calculationList.push_back( std::bind(T::calculate<Type>, extForce, std::placeholders::_1 ) );
^
The Code:
#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);
}
Looks like you're missing the template keyword. If T is a template parameter and T::calculate refers to a template you need to tell the compiler that calculate is a template and not some static variable which you try to compare using the less-than operator with something else:
T::template calculate<Type>
I ran into the exact same problem a couple of years ago but today (post C++11) I would probably solve it with a lambda which is simpler:
std::function<void(Type*)> func = [obj](Type*param){obj.calculate(param);};
Anyhow, try to reduce the number of new
uses. Look for a better way to manage your resources. Your code seems to leak a couple of functors.