8

假设我有这 3 个不同的功能,我可能想指出:

float test1(int a, int b) {
    return 7.0f;
}

struct TestClass {
    float test2(int a, int b) {
        return 5.0f;
    }
};

struct TestClass2 {
    float  test3(int a, int b) {
        return 3.0f;
    }
};

注意所有三个如何使用相同的参数和返回值。我想抽象出它是否是成员函数以及它属于哪个类。我想要一个委托类型,它可以引用这三个函数中的任何一个,仅取决于它的初始化方式。

这是我的第一次尝试:

typedef std::function<float(int, int)> MyDelegate; // is this right?

int main() {
    TestClass obj; 
    TestClass2 obj2;

    MyDelegate a = test1;
    MyDelegate b = std::bind(std::mem_fn(&TestClass::test2), obj); // is this right?
    MyDelegate c = std::bind(std::mem_fn(&TestClass2::test3), obj2); // is this right?

    return 0;
}

这个想法是我也想在包装器中存储“this”指针。这样,它就像一个功能齐全的委托。例如,调用 'b(x, y)' 应该像调用obj.test2(x, y).

我什至无法编译它,我可能没有完全掌握这一点。我对这些库有点陌生,VS2012 中的错误是灾难性的,无济于事。任何帮助,将不胜感激。

4

3 回答 3

11

您需要告诉std::bind如何处理其他函数参数。为了使调用b(x, y)委托xy两个原始函数参数,您需要使用std::placeholders命名空间中的占位符:

std::bind(&TestClass::test2, obj, std::placeholders::_1, std::placeholders::_2);

而且也没有必要std::mem_fn(尽管它有效),因为std::bind已经正确处理了成员函数(使隐式this参数成为显式的第一个参数,就像这样std::mem_fn做)。

于 2012-09-13T10:48:22.017 回答
4

您需要向 std::bind 提供 2 个参数或提供占位符以便稍后提供它们:

std::function<float(int, int)> c = std::bind(&TestClass2::test3, obj2, 1, 2);
c(); //returns result

或者

std::function<float(int, int)> c = std::bind(&TestClass2::test3, obj2, std::placeholders::_1, std::placeholders::_2);
c(1, 2); //returns result

有关 std::bind 的更多信息在这里

于 2012-09-13T10:29:25.850 回答
2

使用可视化 C++ 编译器(CTP 2012)我窥探了他们是如何做 std::function 的,并提供了我自己的解决方案来处理成员函数

用法如下:http: //ideone.com/v5zfDn

class Window
{
public:
    void Show( int number ) const
    {
        //...
    }

    void ShowDynamic( int number ) volatile
    {
        //...
    }
};

void ShowWindows( int param )
{
    //...
}

int main()
{
    Window window;

    typedef mezutils::Delegate< void( int ) > Notifier;
    Notifier notifier;

    notifier = &ShowWindows;
    notifier( 0 );

    notifier = Notifier( &window, &Window::Show );
    notifier( 1 );

    notifier = [](int x) { /*...*/ };
    notifier( 2 );

    void (*funpc)(int) = func;
    notifier = funpc;
    notifier( 3 );

    notifier = [](int arg) { printf("asd %d\r\n",arg); };
    notifier(4);
    return 0;
}

委托类看起来像:http: //ideone.com/DebQgR

当然这是一个有趣的原型,但我喜欢它,因为它很清楚

于 2013-09-30T18:54:13.973 回答