Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.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++ 泛型成员函数指针帮助_C++_Generics_Function Pointers - Fatal编程技术网

C++ 泛型成员函数指针帮助

C++ 泛型成员函数指针帮助,c++,generics,function-pointers,C++,Generics,Function Pointers,嘿,我有一个关于普通成员函数指针的问题。我正试图实现类似于以下问题的目标 本质上,我希望能够注册一个成员函数指针,该指针接受一个泛型事件对象作为其具有特定事件类型(例如,KeyboardEvent)的参数。然后,在我的输入管理类中,我希望能够做到的是,每当用户点击一个键时,我就可以创建一个KeyboardEvent对象,其中包含一些关于按键的数据,并调用所有我用KeyboardEvent对象作为参数注册的KeyboardEvent类型的成员函数指针 我一直在玩boost bind和boost函数

嘿,我有一个关于普通成员函数指针的问题。我正试图实现类似于以下问题的目标

本质上,我希望能够注册一个成员函数指针,该指针接受一个泛型事件对象作为其具有特定事件类型(例如,KeyboardEvent)的参数。然后,在我的输入管理类中,我希望能够做到的是,每当用户点击一个键时,我就可以创建一个KeyboardEvent对象,其中包含一些关于按键的数据,并调用所有我用KeyboardEvent对象作为参数注册的KeyboardEvent类型的成员函数指针

我一直在玩boost bind和boost函数,它们似乎使我能够完成95%的任务,唯一的问题是我试图将所有成员函数指针存储在一个向量中,但它们都是不同类型的,所以我不能这样做。因此,当我第一次向我的事件处理系统注册该方法时,我将它们绑定到一个函数对象中,该系统希望我在执行过程中指定此时的所有参数。我不必在这一点上创建对象,因为这些对象是由将来的未知事件生成的


如果这些都没有意义,很抱歉。

如果我正确理解您的问题,您可以尝试以下内容

// function pointer, function with similar signature can be cast as function_t
typedef int (*function_t)(object_t *event, ...);
std:: vector<function_t> function_pointers;

// populate vector, e.g. function_pointers.push_back((function_t)&some_function)

void handle_event(object_t *event) {
  for (...) (function_pointers.at(i))(event, ...);
}
//函数指针,具有类似签名的函数可以转换为函数\u t
typedef int(*函数)(对象*事件,…);
std::向量函数_指针;
//填充向量,例如函数指针。向后推((函数)和某些函数)
无效句柄事件(对象事件){
对于(…)(函数_指针.at(i))(事件,…);
}
我重读了你的问题,终于抓住了成员函数部分。为此,可以使用函子

struct base {
  virtual void function(event_t *event)= 0;
};

template<class A>
struct F : base { 
  F(A &a) : object_(a) {}
  virtual void function(event_t *a) { object_.function(a); }
  A &object_;
};

std:: vector<base*> callback_vector;
...
callback_vector.push_back(new F<event_handler>(event_handler_object));
struct base{
虚空函数(event_t*event)=0;
};
模板
结构F:base{
F(A&A):对象{(A){}
虚空函数(event_t*a){object_.function(a);}
A&object;
};
std::vector callback\u vector;
...
回调向量。推回(新的F(事件处理程序对象));

如果我正确理解您的问题,您可以尝试以下内容

// function pointer, function with similar signature can be cast as function_t
typedef int (*function_t)(object_t *event, ...);
std:: vector<function_t> function_pointers;

// populate vector, e.g. function_pointers.push_back((function_t)&some_function)

void handle_event(object_t *event) {
  for (...) (function_pointers.at(i))(event, ...);
}
//函数指针,具有类似签名的函数可以转换为函数\u t
typedef int(*函数)(对象*事件,…);
std::向量函数_指针;
//填充向量,例如函数指针。向后推((函数)和某些函数)
无效句柄事件(对象事件){
对于(…)(函数_指针.at(i))(事件,…);
}
我重读了你的问题,终于抓住了成员函数部分。为此,可以使用函子

struct base {
  virtual void function(event_t *event)= 0;
};

template<class A>
struct F : base { 
  F(A &a) : object_(a) {}
  virtual void function(event_t *a) { object_.function(a); }
  A &object_;
};

std:: vector<base*> callback_vector;
...
callback_vector.push_back(new F<event_handler>(event_handler_object));
struct base{
虚空函数(event_t*event)=0;
};
模板
结构F:base{
F(A&A):对象{(A){}
虚空函数(event_t*a){object_.function(a);}
A&object;
};
std::vector callback\u vector;
...
回调向量。推回(新的F(事件处理程序对象));

这并不是对你的问题的真正回答,只是一个暗示,表明你正在努力实现的目标已经存在

看起来您正在尝试实现观察者模式。你可以读到它。掌握了观察者模式后,请查看库。
boost::signal
类似于事件处理程序函数指针的向量,但功能更强大

下面是使用Boost::Signals2检测输入字符的示例。希望能有帮助

#include <iostream>
#include <boost/signals2.hpp>
#include <boost/bind.hpp>

//-----------------------------------------------------------------------------
struct KeyboardEvent
{
    char key;
};

//-----------------------------------------------------------------------------
class Keyboard
{
private:
    typedef boost::signals2::signal<void (KeyboardEvent)> SignalType;
    SignalType signal_;

public:
    typedef SignalType::slot_type SlotType;

    // Subscribes to keyboard events
    boost::signals2::connection connect(const SlotType& slot)
    {
        return signal_.connect(slot);
    }

    // Scans for keyboard events and notifies subscribers
    void scan()
    {
        KeyboardEvent event;
        std::cin >> event.key;
        signal_(event);
    }
};

//-----------------------------------------------------------------------------
class KeyPrinter
{
private:
    void onKey(KeyboardEvent event)
    {
        std::cout << "You hit \'" << event.key << "\'\n";
    }

    boost::signals2::connection connection_;

public:
    void connect(Keyboard& keyb)
    {
        connection_ = keyb.connect(
            boost::bind(&KeyPrinter::onKey, this, _1) );
    }
    void disconnect() {connection_.disconnect();}
};

//-----------------------------------------------------------------------------
class Quitter
{
private:
    void onKey(KeyboardEvent event)
    {
        if (event.key == 'q' || event.key == 'Q') {quit_ = true;}
    }

    boost::signals2::connection connection_;
    bool quit_;

public:
    void connect(Keyboard& keyb)
    {
        quit_ = false;
        connection_ = keyb.connect(
            boost::bind(&Quitter::onKey, this, _1) );
    }
    void disconnect() {connection_.disconnect();}
    bool quitDetected() {return quit_;}
};

//-----------------------------------------------------------------------------
int main()
{
    Keyboard keyb;
    KeyPrinter printer;
    Quitter quitter;

    printer.connect(keyb);
    quitter.connect(keyb);

    while (!quitter.quitDetected())
    {
        keyb.scan();
    }
}
#包括
#包括
#包括
//-----------------------------------------------------------------------------
结构键盘事件
{
字符键;
};
//-----------------------------------------------------------------------------
类键盘
{
私人:
类型DEF增压::信号2::信号信号类型;
信号类型信号;
公众:
typedef SignalType::slot_type SlotType;
//订阅键盘事件
boost::signals2::连接连接(const SlotType和slot)
{
返回信号连接(槽);
}
//扫描键盘事件并通知订阅者
无效扫描()
{
键盘事件;
std::cin>>event.key;
信号(事件);
}
};
//-----------------------------------------------------------------------------
类键打印机
{
私人:
void onKey(键盘事件)
{

这并不是你问题的真正答案,只是暗示你正在努力完成的事情已经存在

您似乎正在尝试实现观察器模式。您可以了解它。一旦掌握了观察器模式,请查看库。
boost::signal
就像事件处理程序函数指针的向量,但功能更强大

下面是一个使用Boost::Signals2检测输入字符的示例。希望对您有所帮助

#include <iostream>
#include <boost/signals2.hpp>
#include <boost/bind.hpp>

//-----------------------------------------------------------------------------
struct KeyboardEvent
{
    char key;
};

//-----------------------------------------------------------------------------
class Keyboard
{
private:
    typedef boost::signals2::signal<void (KeyboardEvent)> SignalType;
    SignalType signal_;

public:
    typedef SignalType::slot_type SlotType;

    // Subscribes to keyboard events
    boost::signals2::connection connect(const SlotType& slot)
    {
        return signal_.connect(slot);
    }

    // Scans for keyboard events and notifies subscribers
    void scan()
    {
        KeyboardEvent event;
        std::cin >> event.key;
        signal_(event);
    }
};

//-----------------------------------------------------------------------------
class KeyPrinter
{
private:
    void onKey(KeyboardEvent event)
    {
        std::cout << "You hit \'" << event.key << "\'\n";
    }

    boost::signals2::connection connection_;

public:
    void connect(Keyboard& keyb)
    {
        connection_ = keyb.connect(
            boost::bind(&KeyPrinter::onKey, this, _1) );
    }
    void disconnect() {connection_.disconnect();}
};

//-----------------------------------------------------------------------------
class Quitter
{
private:
    void onKey(KeyboardEvent event)
    {
        if (event.key == 'q' || event.key == 'Q') {quit_ = true;}
    }

    boost::signals2::connection connection_;
    bool quit_;

public:
    void connect(Keyboard& keyb)
    {
        quit_ = false;
        connection_ = keyb.connect(
            boost::bind(&Quitter::onKey, this, _1) );
    }
    void disconnect() {connection_.disconnect();}
    bool quitDetected() {return quit_;}
};

//-----------------------------------------------------------------------------
int main()
{
    Keyboard keyb;
    KeyPrinter printer;
    Quitter quitter;

    printer.connect(keyb);
    quitter.connect(keyb);

    while (!quitter.quitDetected())
    {
        keyb.scan();
    }
}
#包括
#包括
#包括
//-----------------------------------------------------------------------------
结构键盘事件
{
字符键;
};
//-----------------------------------------------------------------------------
类键盘
{
私人:
类型DEF增压::信号2::信号信号类型;
信号类型信号;
公众:
typedef SignalType::slot_type SlotType;
//订阅键盘事件
boost::signals2::连接连接(const SlotType和slot)
{
返回信号连接(槽);
}
//扫描键盘事件并通知订阅者
无效扫描()
{
键盘事件;
std::cin>>event.key;
信号(事件);
}
};
//-----------------------------------------------------------------------------
类键打印机
{
私人:
void onKey(键盘事件)
{
std::cout(这里是对boost::function/bind问题的更直接的回答,没有boost.Signals2的内容。)

在使用boost::bind时,似乎没有使用_1、_2等占位符。此示例说明了应如何使用它们:

struct KeyboardEvent { char key; };

typedef boost::function<void (KeyboardEvent)> KeyboardHandler;

struct Handler
{
    void onKey(KeyboardEvent event) {std::cout << event.key;}
};

int main()
{
    Handler handler1, handler2;
    std::vector<KeyboardHandler> handlers;
    handlers.push_back(boost::bind(&Handler::onKey, &handler1, _1));
    handlers.push_back(boost::bind(&Handler::onKey, &handler2, _1));
    KeyboardEvent event;
    event.key = 'z';
    handlers[0](event);
    handlers[1](event);
}
struct KeyboardEvent{char key;};
typedef boost::函数键盘处理程序;