尝试使用成员函数创建模板函数时遇到问题

时间:2018-04-25 21:04:24

标签: c++

我正在使用c ++中的TCP套接字制作网络 当我试图将数据包处理程序保存在地图中时,我遇到了问题 这是我的实施:

using handler_t = std::function<void (NetworkClient *, NetworkMessage *)>;
using handlers_t = std::unordered_map<int32_t, handler_t>;

template <typename T, typename V>
using typed_handler_t = void (T::*)(NetworkClient *, V *);

class AbstractPacketHandler {
public:
    void init() {
       define_handlers(_handlers);
    }

    void parse_packet(NetworkClient *client, NetworkMessage *msg) {
        lock_t lock(_locker);
        try {
            _handlers.at(msg->getProtocolId())(client, msg);
        } catch (std::exception &e) {
            throw std::runtime_error("no handler found for protocol id " + msg->getProtocolId());
        }
    }

    virtual void define_handlers(handlers_t &handlers) = 0;

protected:

    template <typename T, typename V>
    handler_t handler(T &holder, typed_handler_t<T, V> addr) {
        return [&holder, &addr](NetworkClient *client, NetworkMessage *msg) mutable {
            (holder.*addr)(client, dynamic_cast<V *>(msg));
        };
    }

private:
    handlers_t _handlers;
    std::mutex _locker;
};

数据包处理程序实现

using Self = MasterPacketHandler;

void Self::define_handlers(handlers_t &handlers) {
    handlers[HelloConnectMessage::PROTOCOL_ID] = handler<Self, HelloConnectMessage>(*this, &Self::onHello);
    handlers[AwesomeMessage::PROTOCOL_ID] = handler<Self, AwesomeMessage>(*this, &Self::onAwesomeMsg);
}

void Self::onHello(NetworkClient *client, HelloConnectMessage *msg) {
    printf("deserialized hellomsg: %d\n", msg->getHelloVar());
}

void Self::onAwesomeMsg(NetworkClient *client, AwesomeMessage *msg) {
    printf("deserialized awesome: %s %d\n", msg->getAwesome(), msg->getSomeNumber());
}

此代码编译没有警告或错误。但是在收到消息的运行时,我得到segmentation fault 在多次尝试修复后,我尝试使用valgrind进行调试 返回错误下方:

==14561== Conditional jump or move depends on uninitialised value(s)
==14561==    at 0x117CDD: std::function<void (NetworkClient*, NetworkMessage*)> AbstractPacketHandler::handler<SlavePacketHandler, AwesomeMessage>(SlavePacketHandler&, void (SlavePacketHandler::*)(NetworkClient*, AwesomeMessage*))::{lambda(NetworkClient*, NetworkMessage*)#1}::operator()(NetworkClient*, NetworkMessage*) (AbstractPacketHandler.h:40)
==14561== Use of uninitialised value of size 8
==14561==    at 0x117D3C: std::function<void (NetworkClient*, NetworkMessage*)> AbstractPacketHandler::handler<SlavePacketHandler, AwesomeMessage>(SlavePacketHandler&, void (SlavePacketHandler::*)(NetworkClient*, AwesomeMessage*))::{lambda(NetworkClient*, NetworkMessage*)#1}::operator()(NetworkClient*, NetworkMessage*) (AbstractPacketHandler.h:40)
==14561== Jump to the invalid address stated on the next line
==14561==    at 0x0: ???
==14561==    by 0x117EEA: std::_Function_handler<void (NetworkClient*, NetworkMessage*), std::function<void (NetworkClient*, NetworkMessage*)> AbstractPacketHandler::handler<SlavePacketHandler, AwesomeMessage>(SlavePacketHandler&, void (SlavePacketHandler::*)(NetworkClient*, AwesomeMessage*))::{lambda(NetworkClient*, NetworkMessage*)#1}>::_M_invoke(std::_Any_data const&, NetworkClient*&&, NetworkMessage*&&) (functional:1731)
==14561== Process terminating with default action of signal 11 (SIGSEGV)
==14561==  Bad permissions for mapped region at address 0x0
==14561==    at 0x0: ???
==14561==    by 0x117EEA: std::_Function_handler<void (NetworkClient*, NetworkMessage*), std::function<void (NetworkClient*, NetworkMessage*)> AbstractPacketHandler::handler<SlavePacketHandler, AwesomeMessage>(SlavePacketHandler&, void (SlavePacketHandler::*)(NetworkClient*, AwesomeMessage*))::{lambda(NetworkClient*, NetworkMessage*)#1}>::_M_invoke(std::_Any_data const&, NetworkClient*&&, NetworkMessage*&&) (functional:1731)

在所有这些错误中,我们都可以看到AbstractPacketHandler:40,这是我handler方法的以下代码行。 (holder.*addr)(client, dynamic_cast<V *>(msg));

我不明白错误,所有变量都被初始化,因为它们是函数的参数..我的处理程序方法是否写得正确?

0 个答案:

没有答案