简体   繁体   English

在C ++ 11中使用std :: function作为委托

[英]Using std::function as a delegate in C++11

Say I have these 3 different functions that I may want to point to: 假设我有这三种不同的功能,我可能想指出:

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;
    }
};

Notice how all three use the same arguments and return value. 注意所有三个都使用相同的参数并返回值。 I want to abstract away whether or not it is a member function and which class it belonged to. 我想要抽象出它是否是一个成员函数以及它属于哪个类。 I want a delegate type that could be referring to any of these 3 functions depending only on how it was initialized. 我想要一个委托类型,它可以引用这3个函数中的任何一个,这取决于它是如何初始化的。

Here is my first attempt: 这是我的第一次尝试:

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;
}

The idea is I want to also store the 'this' pointer inside the wrapper too. 我的想法是,我也想将'this'指针存储在包装器中。 This way, it's like a fully functional delegate.For example, invoking 'b(x, y)' should be like calling obj.test2(x, y) . 这样,它就像一个功能齐全的委托。例如,调用'b(x,y)'就像调用obj.test2(x, y)

I just can't even make it compile, I'm probably not fully grasping this. 我甚至无法编译,我可能还没有完全掌握它。 I'm kind of new to these libraries and the errors in VS2012 are catastrophically unhelpful. 我是这些库的新手,VS2012中的错误是灾难性的无益的。 Any help would be appreciated. 任何帮助,将不胜感激。

You need to tell std::bind what to do with the other function parameters. 你需要告诉std::bind如何处理其他函数参数。 In order to make the call b(x, y) delegate x and y to the two original function parameters you need to use placeholders from the std::placeholders namespace: 为了使调用b(x, y)xy委托给两个原始函数参数,您需要使用std::placeholders命名空间中的std::placeholders

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

And there's also no need for std::mem_fn (it works, though), since std::bind already handles member functions correctly (making the implicit this argument an explicit first argument, like std::mem_fn does). 而且也不需要std::mem_fn (虽然它可以工作),因为std::bind已经正确处理成员函数(使隐式this参数成为显式的第一个参数,就像std::mem_fn一样)。

You need to provide 2 arguments to std::bind or provide placeholders to provide them later: 您需要为std :: bind提供2个参数,或者提供占位符以便以后提供它们:

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

OR 要么

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

More information about std::bind is here . 有关std :: bind的更多信息,请点击此处

Using visual C++ compiler (CTP 2012) i spied how they did std::function and deliviered my own solution to handle member functions 使用visual C ++编译器(CTP 2012)我发现了他们如何使用std :: function并提供了我自己的解决方案来处理成员函数

usage looks like: http://ideone.com/v5zfDn 用法如下: 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;
}

delegate class looks like: http://ideone.com/DebQgR 委托类看起来像: http//ideone.com/DebQgR

of course it is a prototype made for fun, but i like it because it's clear 当然它是一个有趣的原型,但我喜欢它,因为它很清楚

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM