问题
I am trying to create a library where the user can modify the behaviour of a function on an instance-level and still manage to access the members of this instance. This post is the continuation of this thread which is the continuation of this one. Praetorian suggested me to use std::function/bind to do that. Unfortunately, I have two errors:
Pb #1: error: no matching function for call to ‘Child1::BindIt()’
Pb #2: error: no match for ‘operator=’ (operand types are ‘std::function’ and ‘std::_Bind_helper)(const double&), Child1, const std::_Placeholder<1>&>::type {aka std::_Bind(Child1, std::_Placeholder<1>))(const double&)>}’)
I don't understand how to solve these problems.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <functional>
using namespace std;
template<typename T,typename D> T fcn_default(const D &obj, const T &phit){
return 3.2 + phit;
}
template<typename T> class Parent{
public:
Parent() {}
T do_something(const T &phit){
return this->fcn_ptr(phit);
}
std::function<T(const T&)> fcn_ptr;
};
template<typename T> class Child1 : public Parent<T>{
public:
Child1() {
BindIt( &fcn_default< T , Child1<T> > ); // Pb #1: here
}
void BindIt(T (*ptr_in)(const T &) ){
Parent<T>::fcn_ptr = std::bind(&ptr_in, this, std::placeholders::_1); // Pb #2: here
}
};
template<typename T> class Child2 : public Parent<T>{
public:
Child2() {
BindIt( &fcn_default< T , Child2<T> > ); // Pb #1: and here
}
void BindIt(T (*ptr_in)(const T &) ){
Parent<T>::fcn_ptr = std::bind(&ptr_in, this, std::placeholders::_1);
}
T param2;
};
template<typename T> T fcn_mod1 (const Child1<T> &obj, const T &phit){
return 1.2 + phit;
}
template<typename T> T fcn_mod2 (const Child2<T> &obj, const T &phit){
return 2.2 + phit + obj.param2*0.001;
}
typedef double lrtType;
int main(){
std::vector< Parent<lrtType> * > objects;
Child1<lrtType> *test11 = new Child1<lrtType>();
objects.push_back(test11);
Child1<lrtType> *test12 = new Child1<lrtType>();
//test12->BindIt(&fcn_mod1);
objects.push_back(test12);
Child2<lrtType> *test2 = new Child2<lrtType>();
//test2->BindIt(&fcn_mod2);
test2->param2 = 4;
objects.push_back(test2);
for (size_t i = 0; i < objects.size(); ++i) {
std::cout << objects[i]->do_something(2) << std::endl;
}
std::cout << "test" << std::endl;
}
+++++ UPDATE +++++
I updated the code but I still have problem #2
Pb #2: error: no match for ‘operator=’ (operand types are ‘std::function’ and ‘std::_Bind_helper)(const double&), Child1, const std::_Placeholder<1>&>::type {aka std::_Bind(Child1, std::_Placeholder<1>))(const double&)>}’)
#include <iostream>
#include <vector>
#include <cstdlib>
#include <functional>
using namespace std;
template<typename T,typename D> T fcn_default(const D &obj, const T &phit){
return 3.2 + phit;
}
template<typename T> class Parent{
public:
Parent() {}
virtual T do_something (const T &phit) const = 0;
};
template<typename T> class Child1 : public Parent<T>{
public:
Child1() {
Child1<T>::BindIt( &fcn_default< T , Child1<T> > );
}
void BindIt(T (*ptr_in)(const Child1 &, const T &) ){
fcn_ptr = std::bind(&ptr_in, this, std::placeholders::_1); // Problem here
}
std::function<T(const Child1 &, const T &)> fcn_ptr;
T do_something(const T &phit) const {
return this->fcn_ptr(*this,phit);
}
};
template<typename T> class Child2 : public Parent<T>{
public:
Child2() {
Child2<T>::BindIt( &fcn_default< T , Child2<T> > );
}
void BindIt(T (*ptr_in)(const Child2 &, const T &) ){
fcn_ptr = std::bind(&ptr_in, this, std::placeholders::_1); // And here
}
std::function<T(const Child2 &, const T &)> fcn_ptr;
T do_something(const T &phit) const {
return this->fcn_ptr(*this,phit);
}
T param2;
};
template<typename T> T fcn_mod1 (const Child1<T> &obj, const T &phit){
return 1.2 + phit;
}
template<typename T> T fcn_mod2 (const Child2<T> &obj, const T &phit){
return 2.2 + phit + obj.param2*0.001;
}
typedef double lrtType;
int main(){
std::vector< Parent<lrtType> * > objects;
Child1<lrtType> *test11 = new Child1<lrtType>();
objects.push_back(test11);
Child1<lrtType> *test12 = new Child1<lrtType>();
//test12->BindIt(&fcn_mod1);
objects.push_back(test12);
Child2<lrtType> *test2 = new Child2<lrtType>();
//test2->BindIt(&fcn_mod2);
test2->param2 = 4;
objects.push_back(test2);
for (size_t i = 0; i < objects.size(); ++i) {
std::cout << objects[i]->do_something(2) << std::endl;
}
std::cout << "test" << std::endl;
}
回答1:
If somebody is interested, below is a solution that works. There is however important duplication of code and I fear I can not avoid it...
#include <iostream>
#include <vector>
#include <cstdlib>
#include <functional>
using namespace std;
template<typename T,typename D> T fcn_default(const D &obj, const T &phit){
return 3.2 + phit;
}
template<typename T> class Parent{
public:
Parent() {}
virtual T do_something (const T &phit) const = 0;
};
template<typename T> class Child1 : public Parent<T>{
public:
Child1() {
fcn_ptr = &fcn_default< T , Child1<T> >;
}
std::function<T(const Child1<T> &, const T &)> fcn_ptr;
T do_something(const T &phit) const {
return (*this).fcn_ptr(*this,phit);
}
};
template<typename T> class Child2 : public Parent<T>{
public:
Child2() {
fcn_ptr = &fcn_default< T , Child2<T> >;
}
std::function<T(const Child2<T> &, const T &)> fcn_ptr;
T do_something(const T &phit) const {
return (*this).fcn_ptr(*this,phit);
}
T param2;
};
template<typename T> T fcn_mod1 (const Child1<T> &obj, const T &phit){
return 1.2 + phit;
}
template<typename T> T fcn_mod2 (const Child2<T> &obj, const T &phit){
return 2.2 + phit + obj.param2*0.001;
}
typedef double lrtType;
int main(){
std::vector< Parent<lrtType> * > objects;
Child1<lrtType> *test11 = new Child1<lrtType>();
objects.push_back(test11);
Child1<lrtType> *test12 = new Child1<lrtType>();
test12->fcn_ptr = &fcn_mod1<lrtType>;
objects.push_back(test12);
Child2<lrtType> *test2 = new Child2<lrtType>();
test2->fcn_ptr = &fcn_mod2<lrtType>;
test2->param2 = 4;
objects.push_back(test2);
for (size_t i = 0; i < objects.size(); ++i) {
std::cout << objects[i]->do_something(2) << std::endl;
}
std::cout << "test" << std::endl;
}
来源:https://stackoverflow.com/questions/24249909/no-matching-function-for-call-to-unresolved-overloaded-function-type