我需要在运行时选择类的特定方法。为此,我使用std::bind
.下面是一个演示我工作的示例:
#include<iostream>
#include<functional>
class bc {
public:
bc(int, double);
std::function<double(double)> f; //pointer to function which will be binded with f1 or f2
void setVal(double v) {val = v;} //method allowing to change val
double val; //some variable used by f1 and f2
double f1(double v) {return 2*v*val;}
double f2(double v) {return 3*v*val;}
};
bc::bc(int fid, double v) //depends on fid the f1 or f2 is chosen for binding
{
using namespace std::placeholders;
this->val = v;
if(fid == 1)
f = std::bind(&bc::f1, *this, _1);
else
f = std::bind(&bc::f2, *this, _1);
}
所以取决于赋予构造函数的fid
值,选择必要的实现(f1
或f2
)。然后在main
:
int main()
{
bc my(1, 2.0);
std::cout << my.f(1) << std::endl; //1
my.setVal(5.0);
std::cout << my.f(1) << std::endl; //2
return 0;
}
字符串//1
的第一个输出符合预期:4
。 但是第二个输出(//2
)也是4
的,而它应该是10
的,因为val
的值应该被my.setVal(5.0)
更改为5
。
我希望在绑定阶段制作了类的副本之类的东西,my.setVal(5.0)
更改val
对这个"副本"没有影响。
如何解决这个问题?或者可能有更好的方法可以在某个函数的多个实现之间进行运行时选择。
在将this
传递给std::bind
之前,不要取消引用:
if(fid == 1)
f = std::bind(&bc::f1, this, _1);
else
f = std::bind(&bc::f2, this, _1);
默认情况下,std::bind
存储参数的副本,因此您最终会在其中获得bc
的副本,并且更改原始参数的val
字段不起作用。或者,您可以使用std::reference_wrapper
来实现相同的效果:
if(fid == 1)
f = std::bind(&bc::f1, std::ref(*this), _1);
else
f = std::bind(&bc::f2, std::ref(*this), _1);
*this
会导致绑定当前对象的副本,请改用this
或std::ref(*this)
。