Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用'std::function'从另一个对象调用对象的成员`_C++_Oop_C++11_Callback_Std Function - Fatal编程技术网

C++ 使用'std::function'从另一个对象调用对象的成员`

C++ 使用'std::function'从另一个对象调用对象的成员`,c++,oop,c++11,callback,std-function,C++,Oop,C++11,Callback,Std Function,我试图在对象之间创建一个通信系统,其中控制器对象保留其他对象的成员函数向量,并在需要时调用它们。 我读了几篇关于std::function用法的文章,但找不到一篇介绍这个用例的文章 我的代码是: #include <functional> #include <Windows.h> class Callable { }; class ClassA : public Callable { public: double CallThis(doubl

我试图在对象之间创建一个通信系统,其中控制器对象保留其他对象的成员函数向量,并在需要时调用它们。
我读了几篇关于
std::function
用法的文章,但找不到一篇介绍这个用例的文章

我的代码是:

#include <functional>
#include <Windows.h>

class Callable
{

};

class ClassA : public Callable
{
    public:
        double CallThis(double x, int y) const
        {
            MessageBoxW(NULL, L"CallThis() is called.", L"In ClassA", MB_ICONINFORMATION);
            return x + y;
        }
};

class ClassB : public Callable
{
    public:
        double CallMe(double x, int y) const
        {
            MessageBoxW(NULL, L"CallMe() is called.", L"In ClassB", MB_ICONINFORMATION);
            return x + y;
        }
};

class Caller
{
    public:
        void AddSubscriber( const Callable & ObjectToCall,
                            const std::function<double(const Callable &, double, int)> & Subscriber)
        {
            Subscribers.push_back(Subscriber);
            ObjectsToBeCalled.push_back(ObjectToCall);
        }
        void CallSubscribers()
        {
            for (size_t i=0; i<Subscribers.size(); i++)
            {
                Subscribers[i](ObjectsToBeCalled[i], 1.0, 2);
            }
        }
    private:
        std::vector<std::function<double(const Callable &, double, int)>> Subscribers;
        std::vector<const Callable &> ObjectsToBeCalled;
};

int APIENTRY wWinMain(  _In_        HINSTANCE   hInstance,
                        _In_opt_    HINSTANCE   hPrevInstance,
                        _In_        LPTSTR      lpCmdLine,
                        _In_        int         nCmdShow)
{
    // ...

    ClassA ObjectA;
    ClassB ObjectB;
    Caller ObjectCaller;
    ObjectCaller.AddSubscriber(ObjectA, &ClassA::CallThis);
    ObjectCaller.AddSubscriber(ObjectA, &ClassB::CallMe);
    Sleep(5000);
    ObjectCaller.CallSubscribers();

    // ...
}
我做错了什么?如何运行此代码


(我的IDE是Microsoft Visual Studio 2012。)

查看您的代码,您最好先存储
std::function
,然后使用
std::bind
将对象绑定到成员函数

template <typename F>
void AddSubscriber( const Callable & obj,
                    F subscriber)
{
    Subscribers.push_back(std::bind(subscriber, obj, _1, _2));
}
然后从调用方进行绑定

Caller c;
ClassA a;
using namespace std::placeholders;
c.AddSubscriber(std::bind(&ClassA::CallThis, a, _1, _2));

在阅读完juanchopanza的答案后,我重写了我的代码,如附件所示。现在,它的工作如预期

class ClassA
{
    public:
        double CallThis(double x, int y) const
        {
            MessageBoxW(NULL, L"CallThis() is called.", L"In ClassA", MB_ICONINFORMATION);
            return x + y;
        }
};

class ClassB
{
    public:
        double CallMe(double x, int y) const
        {
            MessageBoxW(NULL, L"CallMe() is called.", L"In ClassB", MB_ICONINFORMATION);
            return x + y;
        }
};

class Caller
{
    public:
        void AddSubscriber(std::function<double(double, int)> Subscriber)
        {
            Subscribers.push_back(Subscriber);
        }
        void CallSubscribers()
        {
            for (const auto & Subscriber : Subscribers)
            {
                Subscriber(1.0, 2);
            }
        }
    private:
        std::vector<std::function<double(double, int)>> Subscribers;
};

int APIENTRY wWinMain(  _In_        HINSTANCE   hInstance,
                        _In_opt_    HINSTANCE   hPrevInstance,
                        _In_        LPTSTR      lpCmdLine,
                        _In_        int         nCmdShow)
{
    // ...

    ClassA ObjectA;
    ClassB ObjectB;
    Caller ObjectCaller;
    ObjectCaller.AddSubscriber(std::bind(&ClassA::CallThis, ObjectA, std::placeholders::_1, std::placeholders::_2));
    ObjectCaller.AddSubscriber(std::bind(&ClassB::CallMe,   ObjectB, std::placeholders::_1, std::placeholders::_2));
    Sleep(5000);
    ObjectCaller.CallSubscribers();

    // ...
}
A类
{
公众:
double CallThis(double x,int y)const
{
MessageBoxW(NULL,L“CallThis()被调用”,L“在ClassA中”,MB_ICONINFORMATION);
返回x+y;
}
};
B类
{
公众:
双CallMe(双x,整数y)常数
{
MessageBoxW(NULL,调用L“CallMe()”,L“在类B中”,MB_ICONINFORMATION);
返回x+y;
}
};
类调用者
{
公众:
void AddSubscriber(std::函数Subscriber)
{
订阅者。推回(订阅者);
}
void CallSubscribers()
{
用于(常数自动和订户:订户)
{
认购人(1.0,2);
}
}
私人:
std::向量订户;
};
国际货币基金组织,
_在当前情况下,
_在LPTSTR lpCmdLine中,
_In_uuint(nCmdShow)
{
// ...
A类对象A;
B类对象B;
调用者对象调用者;
AddSubscriber(std::bind(&ClassA::CallThis,ObjectA,std::placeholders::_1,std::placeholders::_2));
AddSubscriber(std::bind(&ClassB::CallMe,ObjectB,std::placeholders::_1,std::placeholders::_2));
睡眠(5000);
ObjectCaller.CallSubscribers();
// ...
}

std::vector对象被调用您正在尝试声明引用向量。这是非法的,因为vector存储元素的副本,而引用是不可复制的。尝试将其声明为
std::vector
,并查看它是否编译。
std::function
的行为就像是在向其传递指向成员的指针时自动调用
std::mem\u fn
。@Xeo Right,谢谢。我删除了开头的句子。保留一个回调容器似乎更容易管理。FWIW,我建议在这里调用
emplace\u back
Caller c;
ClassA a;
using namespace std::placeholders;
c.AddSubscriber(std::bind(&ClassA::CallThis, a, _1, _2));
class ClassA
{
    public:
        double CallThis(double x, int y) const
        {
            MessageBoxW(NULL, L"CallThis() is called.", L"In ClassA", MB_ICONINFORMATION);
            return x + y;
        }
};

class ClassB
{
    public:
        double CallMe(double x, int y) const
        {
            MessageBoxW(NULL, L"CallMe() is called.", L"In ClassB", MB_ICONINFORMATION);
            return x + y;
        }
};

class Caller
{
    public:
        void AddSubscriber(std::function<double(double, int)> Subscriber)
        {
            Subscribers.push_back(Subscriber);
        }
        void CallSubscribers()
        {
            for (const auto & Subscriber : Subscribers)
            {
                Subscriber(1.0, 2);
            }
        }
    private:
        std::vector<std::function<double(double, int)>> Subscribers;
};

int APIENTRY wWinMain(  _In_        HINSTANCE   hInstance,
                        _In_opt_    HINSTANCE   hPrevInstance,
                        _In_        LPTSTR      lpCmdLine,
                        _In_        int         nCmdShow)
{
    // ...

    ClassA ObjectA;
    ClassB ObjectB;
    Caller ObjectCaller;
    ObjectCaller.AddSubscriber(std::bind(&ClassA::CallThis, ObjectA, std::placeholders::_1, std::placeholders::_2));
    ObjectCaller.AddSubscriber(std::bind(&ClassB::CallMe,   ObjectB, std::placeholders::_1, std::placeholders::_2));
    Sleep(5000);
    ObjectCaller.CallSubscribers();

    // ...
}