我正在尝试创建一个库,用户可以在该库中修改实例级别的函数行为,并仍然设法访问此实例的成员。这篇文章是this thread的延续,它是this one的延续。 Praetorian suggested me使用std :: function / bind来做到这一点。不幸的是,我有两个错误:
Pb#1:错误:没有匹配函数来调用'Child1 :: BindIt()'
Pb#2:错误:'operator ='不匹配(操作数类型是'std :: function'和'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() {}
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 +++++
我更新了代码,但我仍然遇到问题#2
Pb#2:错误:'operator ='不匹配(操作数类型是'std :: function'和'std :: _ Bind_helper)(const double&amp;),Child1 ,const std: :_Placeholder&lt; 1&gt;&amp;&gt; :: type {aka std :: _ Bind(Child1 ,std :: _ Placeholder&lt; 1&gt;))(const double&amp;)&gt;}')
#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;
}
答案 0 :(得分:0)
如果有人感兴趣,下面是一个有效的解决方案。然而,重要的代码重复,我担心我无法避免...
#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;
}