Правильный способ включить член zmq :: socket_t в класс? - PullRequest
0 голосов
/ 19 сентября 2019

В Visual Studio 2017 следующий код не компилируется из-за удаленного конструктора


// MyClass.h

#include <zmq.hpp>

extern zmq::context_t g_context;

class MyCppZMQClass
{
public:
    MyCppZMQClass();
    ~MyCppZMQClass();

private:
    zmq::socket_t m_socket;
};

//  MyClass.cpp

#include "MyCppZMQClass.h"

zmq::context_t g_context = zmq::context_t(1);


MyCppZMQClass::MyCppZMQClass()
    :m_socket(g_context, zmq::socket_type::sub)
{
}


MyCppZMQClass::~MyCppZMQClass()
{
}

main cpp

// hello_cpp.cpp

#include "MyCppZMQClass.h"

int main()
{
    auto mc = MyCppZMQClass();
}

Ошибка компилятора:

1>g:\\hello_cpp\hello_cpp.cpp(73): error C2280: 'MyCppZMQClass::MyCppZMQClass(const MyCppZMQClass &)': attempting to reference a deleted function
1>g:\hello_cpp\mycppzmqclass.h(15): note: compiler has generated 'MyCppZMQClass::MyCppZMQClass' here
1>g:\hello_cpp\mycppzmqclass.h(15): note: 'MyCppZMQClass::MyCppZMQClass(const MyCppZMQClass &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'zmq::socket_t::socket_t(const zmq::socket_t &)'
1>e:\_dev\vcpkg\installed\x64-windows\include\zmq.hpp(1513): note: 'zmq::socket_t::socket_t(const zmq::socket_t &)': function was explicitly deleted

Я проверил, что я вызываю это

// zmq.hpp

#ifdef ZMQ_CPP11
    socket_t(context_t &context_, socket_type type_)
        : socket_t(context_, static_cast<int>(type_))
    {
    }
#endif

и ZMQ_CPP11 определяется с VS2017

// zmq.hpp

#if (defined(__cplusplus) && __cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1900)
    #define ZMQ_CPP11
#endif

Однако, создание объекта сокета в главной функции компилируется.

int main()
{
    zmq::context_t ctx;
    zmq::socket_t sock(ctx, zmq::socket_type::push);
    sock.bind("inproc://test");
    std::string m = "Hello, world";
    sock.send(zmq::buffer(m), zmq::send_flags::dontwait);
}

Что мне здесь не хватает?

Какой конструктор мне следует использовать в моем предыдущем случае?

ОБНОВЛЕНИЕ

Если яудалите мой конструктор копирования и оператор =, проблема сохраняется.

#include <zmq.hpp>

extern zmq::context_t g_context;

class MyCppZMQClass
{
public:
    MyCppZMQClass();
    ~MyCppZMQClass();

    MyCppZMQClass(const MyCppZMQClass&) = delete;
    MyCppZMQClass& operator=(const MyCppZMQClass&) = delete;

private:
    zmq::socket_t m_socket;
};

Ответы [ 2 ]

1 голос
/ 19 сентября 2019
auto mc = MyCppZMQClass();

Здесь вы пытаетесь создать временный объект, а затем использовать конструктор копирования для инициализации переменной из него.Измените на

MyCppZMQClass mc;

или добавьте конструктор / назначение перемещения.

1 голос
/ 19 сентября 2019

пометить конструктор и оператор копирования = как удаленные

Это правильный способ решения этой проблемы.

MyCppZMQClass теперь не запрашивает копируемую или назначаемую копию.

Не забудьте указать опцию перемещения ctor / assign.

...