2

我有两个班级,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++ 方法来做,我会接受:)

谢谢

4

3 回答 3

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 或函数对象转换为它。

于 2013-06-17T13:49:09.360 回答
1

根据您是否拥有 C++11,您可能需要std::bindandstd::functionboost::bindandboost::function用于较旧的 C++ 版本。

绑定允许您获取一个函数并绑定 0 个或多个参数,或者重新排列参数。事实上,你上面的东西看起来像这样:

double ClassA::Foo(double x, ClassB y)
{
    boost::function<double> baz = boost::bind(this, ClassA::Baz, _1, y);
    Bar(baz);
}

Bar 的签名将采用 aboost::function而不是函数指针。

请注意,对于绑定 memeber 函数,我的语法可能略有不同,请查看文档以获取详细信息。

见这里: http: //www.boost.org/doc/libs/1_53_0/libs/bind/bind.html

或在这里:http ://en.cppreference.com/w/cpp/utility/functional/bind

于 2013-06-17T13:52:42.360 回答
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;
}
于 2013-06-17T14:56:06.803 回答