std::function, ошибка C2679

309
06 июня 2017, 00:34
  • Kernel.h

    namespace GateServer
    {
        class CKernel
        {
            using PFMsgHandler = std::function<bool(const char * pMsg, int MsgLen)>
        public:
            bool Initialize();
            PFMsgHandler m_MsgHandler[100];
            bool OnMsgFromCS(const char * pMsg, int MsgLen);
        }
    }
  • Kernel.cpp

    #include "Kernel.h"
    namespace GateServer
    {
        bool CKernel::Initialize()
        {
            m_MsgHandler[0] = &CKernel::OnMsgFromCS; //error
            return true;
        }
    }

При попытке скомпилировать программу получаю следующую ошибку:

Error C2679 binary '=': no operator found which takes a right-hand operand of type 'bool (__thiscall GateServer::CGSKernel::* )(const char *,int)' (or there is no acceptable conversion) GSKernel c:\projects\с++\sonic\server\gateserver\gskernel\gskernel.cpp 28

Answer 1

Вы пытаетесь присвоить std::function указателю на член класса.

Решить проблему можно одним из двух способов:

  1. Сделать PFMsgHandler указателем:

    namespace GateServer
    {
        class CKernel
        {
            using PFMsgHandler = bool(GateServer::*)(const char * pMsg, int MsgLen);
            // ...
  2. Либо заключить указатель внутрь экземпляра std::function:

    #include "Kernel.h"
    namespace GateServer
    {
        bool CKernel::Initialize()
        {
            m_MsgHandler[0] = std::bind(
                &CKernel::OnMsgFromCS,
                this,
                std::placeholders::_1,
                std::placeholders::_2
            );
            return true;
        }
    }
Answer 2

Нестатические методы класса не являются обычными функциями. В частности, у каждого нестатического метода класса концептуально есть скрытый параметр ClassType *this.

В вашем случае метод CKernel::OnMsgFromCS фактически имеет три параметра: CKernel *this, const char * pMsg и int MsgLen. Вы же пытаетесь засунуть указатель на этот метод в std::function , у которого только два параметра. Поэтому и возникает ошибка.

А уж как эту ошибку исправлять зависит от того, что вы пытаетесь сделать.

Answer 3

Есть и 3-й способ решения, для которого нужно немного видоизменить PFMsgHandler:

using PFMsgHandler = std::function<bool(CKernel&, const char * pMsg, int MsgLen)>

И когда будете вызывать экземпляр PFMsgHandler нужно будет передавать объект, для которого функция класса должна быть вызвана, например:

m_MsgHandler[0](*this, "Message", 0);

Конечно, можно в определении PFMsgHandler использовать указатель, а не ссылку, что будет удобнее с this, но будет менее удобно с объектами, которые указателями не являются.

READ ALSO
Ожидание выполнения потока Winapi

Ожидание выполнения потока Winapi

Подскажите, почему выполняется только первый поток? Как можно исправить, что бы выполнялись потоки по очереди?

298
Что значит конструкция if (mas[i] - !!a != a[i])

Что значит конструкция if (mas[i] - !!a != a[i])

Недавно начал изучать C++, столкнулся со странной конструкцией условного оператора и не могу понять что он с чем сравнивает

381
Получить данные с модального окна

Получить данные с модального окна

У меня есть класс основного окна MainWindowС него я запускаю (допустим, при авторизации) модальное окно авторизации с полями "Логин", "Пароль" (lineLogin,...

258