我有两个类,ClassA和ClassB。 ClassA有三种方法:
double Foo(double, ClassB);
double Bar(double (*f)(double));
double Baz(double, ClassB);
我想在Foo中定义一个函数Qux,基于Baz,但没有ClassB类型的参数:即类型为“double Qux(double)”,以便我可以将它传递给Bar:
double ClassA::Foo(double x, ClassB y)
{
// double Qux(double .) = Baz(., y)
Bar((*Qux))
}
有人有任何想法吗?
我想有些人会回答这不是做这件事的好方法。因此,为了解释具体情况,我使用数值方法(http://en.wikipedia.org/wiki/Simpson%27s_rule)定价金融资产以计算积分:
ClassA: FinancialAsset
ClassB: PrincingModel
Foo: FinancialAsset.Price(date, PrincingModel)
Bar: FinancialAsset.SimpsonMethod(FunctionOneArgument)
Baz: FinancialAsset.FunctionTwoArguments(date, PrincingModel)
我正在寻找:
Qux: FunctionOneArgument(date) = FinancialAsset.FunctionTwoArguments(date, PrincingModel)
我不确定解决这种结构的好方法是什么。我有更好的/更多的c ++方法,我会采取:)
谢谢,
卡米尔
答案 0 :(得分:2)
你不能完全这样做,因为你的Bar函数正在使用指向常规函数的指针,但你可以改用它:
class A {
...
public:
double Foo(double, ClassB);
double Bar(std::function<double(double)> f);
double Baz(double, ClassB);
};
double ClassA::Foo(double x, ClassB y)
{
auto Qux = [&](double x) { Baz(x,y); };
return Bar(Qux);
}
std::function
是表示类似函数的对象的更通用的方法。您可以将常规函数,lambda或函数对象转换为它。
答案 1 :(得分:1)
根据您是否拥有C ++ 11,对于较旧的C ++版本,您需要std::bind
和std::function
或boost::bind
和boost::function
。
绑定允许您获取一个函数并绑定0个或多个参数,或重新排列参数。事实上,你上面的东西看起来像这样:
double ClassA::Foo(double x, ClassB y)
{
boost::function<double> baz = boost::bind(this, ClassA::Baz, _1, y);
Bar(baz);
}
Bar的签名将采用boost::function
而不是函数指针。
请注意,我的语法可能稍微偏离绑定memeber函数,请查看文档以获取详细信息。
见这里: http://www.boost.org/doc/libs/1_53_0/libs/bind/bind.html
或者在这里:http://en.cppreference.com/w/cpp/utility/functional/bind
答案 2 :(得分:0)
您可以在不更改任何功能签名(以及C ++ 11或boost)的情况下执行此操作,但如果您可以避免,我不建议您这样做。它很难看,不是线程安全的,而且一般不太好:
#include <iostream>
struct B
{
// some data in B
int i;
};
struct A
{
//some data in A
double d;
// the functions you defined in A
double Foo(double x, B y);
double Bar(double (*f)(double));
double Baz(double x, B y);
};
// a poor substitutes for closures
struct
{
A *a;
B *b;
} hack;
double Qux(double x2)
{
// use the stored pointer to call Baz on x2
return hack.a->Baz(x2, *hack.b);
}
double A::Foo(double x, B y)
{
// store pointers for use in Qux
hack.a = this;
hack.b = &y;
// do something with x
d += x;
double result = Bar(&Qux);
return result;
}
double A::Bar(double (*f)(double))
{
// do something with d, call the passed function
d += 1;
return f(d);
}
double A::Baz(double x, B y)
{
// do something with the passed data
return x + y.i;
}
int main()
{
A a;
a.d = 1.25;
B b;
b.i = 2;
std::cout << a.Foo(.25, b) << std::endl; // should be 4.5
return 0;
}