dimanche 28 décembre 2014

Template std::function as class member function C++

I would like to store a std::function in a class as a member.

I have troubles with below test code when calling a.callMethod() where the method has been set just before with a.setMethod(). The code works fine if I remove the template.

I have tried to debug with a function callMethodOutsideClass without success.

Is there a better way to manage that ?



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

template<typename T>
struct A
{
A(size_t size, T value) : vec_(size, value), method_(nullptr) {}
void setMethod(const std::function<int(A<T>&)> method) { method_ = method; }
int callMethod()
{
if(method_)
return method_(*this);
else
std::cerr << "method not initialized" << std::endl;
return -1;
}

std::vector<int> vec_;
std::function<int(A<T>& a)> method_;
};

template<typename T>
int callMethodOutsideClass(struct A<T>& a, const std::function<int(A<T>&)> method)
{
return method(a);
}

template<typename T>
int apple(struct A<T>& a)
{
a.vec_[0] += 1;
return 1;
}

template<typename T>
int orange(struct A<T>& a)
{
a.vec_[0] += 2;
return 2;
}

int main()
{
A<int> a(10,4), b(10,4);
std::cout << callMethodOutsideClass(a, &apple) << std::endl;

a.setMethod(&orange);
std::cout << a.callMethod() << std::endl;

std::cout << a.vec_[0] << std::endl;
}


I currently get the following errors :



Foo6.cpp: In function ‘int main()’:
Foo6.cpp:46:47: error: cannot resolve overloaded function ‘apple’ based on conversion to type ‘std::function<int(A<int>&)>’
std::cout << callMethodOutsideClass(a, &apple) << std::endl;
^
Foo6.cpp:48:21: error: no matching function for call to ‘A<int>::setMethod(<unresolved overloaded function type>)’
a.setMethod(&orange);
^
Foo6.cpp:48:21: note: candidate is:
Foo6.cpp:9:7: note: void A<T>::setMethod(std::function<int(A<T>&)>) [with T = int]
void setMethod(const std::function<int(A<T>&)> method) { method_ = method; }
^
Foo6.cpp:9:7: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘std::function<int(A<int>&)>’

Aucun commentaire:

Enregistrer un commentaire