debug websocket++ Broadcast_server.cpp («owner_less» не является членом «std»)

Zaphoyd broadcast_server.cpp выглядит как идеальная основа для сервера веб-сокетов, который может быстро принимать и отправлять сообщения и соединения с потоком для реальных действий, чтобы не прерывать связь. https://github.com/zaphoyd/websocketpp/blob/experimental/examples/broadcast_server/broadcast_server.cpp

Его простой пример print_server.cpp легко компилируется; однако я получаю несколько ошибок компиляции с broadcast_server.cpp.

root@server:~# g++ -O3 broadcast_server.cpp -I ~/websocketpp-experimental/ -lboost_system
broadcast_server.cpp:126:37: error: 'owner_less' is not a member of 'std'
broadcast_server.cpp:126:37: error: 'owner_less' is not a member of 'std'
broadcast_server.cpp:126:70: error: 'con_list' was not declared in this scope
broadcast_server.cpp:126:70: error: template argument 2 is invalid
broadcast_server.cpp:126:18: warning: 'typedef' was ignored in this declaration [enabled by default]
broadcast_server.cpp:129:5: error: 'con_list' does not name a type
broadcast_server.cpp: In member function 'void broadcast_server::process_messages()':
broadcast_server.cpp:109:17: error: 'm_connections' was not declared in this scope
broadcast_server.cpp:112:17: error: 'm_connections' was not declared in this scope
broadcast_server.cpp:116:17: error: 'con_list' has not been declared
broadcast_server.cpp:116:36: error: expected ';' before 'it'
broadcast_server.cpp:117:22: error: 'it' was not declared in this scope
broadcast_server.cpp:117:27: error: 'm_connections' was not declared in this scope

Я новичок в С++, и это, вероятно, простые проблемы, но я не могу разобраться с ними.

'owner_less' is not a member of 'std'? http://en.cppreference.com/w/cpp/memory/owner_less

Я предполагаю, что template argument 2 error исчезнет, ​​когда проблема будет решена.

'con_list' was not declared in this scope когда это прямо там, в private:? то же самое с 'm_connections'?

Я предполагаю, что 'con_list' has not been declared исчезнет, ​​когда исчезнет вышеуказанная ошибка.

Я не знаю, о каком 'it' идет речь и почему перед ним стоит ;.

версии

Убунту 12.10

gcc --version gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2

повысить 1.53.0

дополнительные #includes

#include <cstdlib>
#include <iostream>
#include <memory>
#include <set>

еще ничего

-std=c++11

In file included from /usr/include/c++/4.7/map:60:0,
                 from /usr/local/include/boost/date_time/gregorian/greg_month.hpp:18,
                 from /usr/local/include/boost/date_time/gregorian/greg_ymd.hpp:16,
                 from /usr/local/include/boost/date_time/gregorian/greg_calendar.hpp:16,
                 from /usr/local/include/boost/date_time/gregorian/gregorian_types.hpp:19,
                 from /usr/local/include/boost/date_time/posix_time/posix_time_config.hpp:18,
                 from /usr/local/include/boost/date_time/posix_time/posix_time_system.hpp:13,
                 from /usr/local/include/boost/date_time/posix_time/ptime.hpp:12,
                 from /usr/local/include/boost/date_time/posix_time/posix_time_types.hpp:12,
                 from /usr/local/include/boost/thread/thread_time.hpp:11,
                 from /usr/local/include/boost/thread/lock_types.hpp:18,
                 from /usr/local/include/boost/thread/pthread/thread_data.hpp:12,
                 from /usr/local/include/boost/thread/thread.hpp:17,
                 from /usr/local/include/boost/thread.hpp:13,
                 from /root/websocketpp-experimental/websocketpp/common/thread.hpp:41,
                 from /root/websocketpp-experimental/websocketpp/concurrency/basic.hpp:31,
                 from /root/websocketpp-experimental/websocketpp/config/core.hpp:35,
                 from /root/websocketpp-experimental/websocketpp/config/asio_no_tls.hpp:31,
                 from broadcast_server.cpp:1:
/usr/include/c++/4.7/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<boost::weak_ptr<void>, boost::weak_ptr<void>, std::_Identity<boost::weak_ptr<void> >, std::owner_less<boost::weak_ptr<void> >, std::allocator<boost::weak_ptr<void> > >':
/usr/include/c++/4.7/bits/stl_set.h:116:17:   required from 'class std::set<boost::weak_ptr<void>, std::owner_less<boost::weak_ptr<void> > >'
broadcast_server.cpp:132:14:   required from here
/usr/include/c++/4.7/bits/stl_tree.h:471:31: error: invalid use of incomplete type 'struct std::owner_less<boost::weak_ptr<void> >'
In file included from /usr/include/c++/4.7/bits/shared_ptr.h:52:0,
                 from /usr/include/c++/4.7/memory:87,
                 from /usr/local/include/boost/config/no_tr1/memory.hpp:21,
                 from /usr/local/include/boost/smart_ptr/shared_ptr.hpp:27,
                 from /usr/local/include/boost/shared_ptr.hpp:17,
                 from /usr/local/include/boost/date_time/time_clock.hpp:17,
                 from /usr/local/include/boost/thread/thread_time.hpp:9,
                 from /usr/local/include/boost/thread/lock_types.hpp:18,
                 from /usr/local/include/boost/thread/pthread/thread_data.hpp:12,
                 from /usr/local/include/boost/thread/thread.hpp:17,
                 from /usr/local/include/boost/thread.hpp:13,
                 from /root/websocketpp-experimental/websocketpp/common/thread.hpp:41,
                 from /root/websocketpp-experimental/websocketpp/concurrency/basic.hpp:31,
                 from /root/websocketpp-experimental/websocketpp/config/core.hpp:35,
                 from /root/websocketpp-experimental/websocketpp/config/asio_no_tls.hpp:31,
                 from broadcast_server.cpp:1:
/usr/include/c++/4.7/bits/shared_ptr_base.h:270:12: error: declaration of 'struct std::owner_less<boost::weak_ptr<void> >'

как я установил (зависимости, актуальная программа и т.д.)

https://github.com/zaphoyd/websocketpp/wiki/Setup-0.3X-on-Ubuntu-12.10

альтернативы приветствуются

Если у кого есть альтернативы std::owner_less, выкладывайте пожалуйста.


person Community    schedule 15.03.2013    source источник
comment
попробуйте #include ‹память›   -  person Sam Miller    schedule 15.03.2013
comment
@SamMiller Спасибо за внимание! пожалуйста, отредактируйте   -  person    schedule 15.03.2013
comment
Добавить ключ -std=c++11 в командную строку компилятора   -  person borisbn    schedule 15.03.2013
comment
@borisbn вау, я только что получил НАМНОГО больше ошибок, лол. Спасибо, что заглянули!   -  person    schedule 15.03.2013
comment
опубликуйте ошибки, вам нужно С++ 11 для использования std::owner_less   -  person Sam Miller    schedule 15.03.2013
comment
@SamMiller, я превысил лимит, поэтому я публиковал, пока не упомянул std::owner_less   -  person    schedule 15.03.2013


Ответы (2)


std::owner_less — это функция STL C++11, позволяющая помещать std::weak_ptr в ассоциативные контейнеры, такие как set и map. В конечном счете, connection_hdl — это weak_ptr, и именно поэтому ему нужна пользовательская функция сравнения.

WebSocket++ 0.3.x можно настроить с помощью определений препроцессора для использования либо C++03 + Boost, либо C++11. По умолчанию используется C++03 + Boost. Boost weak_ptr работает немного по-другому и не требует пользовательской функции сравнения. Если вы используете список, очередь или вектор, в этом также нет необходимости, поскольку эти контейнеры не используют connection_hdl в качестве ключей.

В большинстве примеров в руководстве по версии 0.3.x и в комплекте с библиотекой используется C++11, потому что он намного чище и лаконичнее. Чтобы скомпилировать и связать эти примеры как есть, вам понадобится компилятор C++11 и использование соответствующих флагов компилятора C++11 и определений WebSocket++. Scons — это система сборки, которую я использую для автоматизации сборки и запуска всех примеров и модульных тестов. Нет необходимости создавать и запускать отдельные примеры программ. Любая другая система сборки должна работать нормально, как и передача аргументов компилятора ad hoc в командной строке.

Я создал страницу в руководстве, которая описывает различные варианты включения/отключения функций C++11. http://www.zaphoyd.com/websocketpp/manual/reference/cpp11-support . На этой странице руководства есть список рекомендуемых флагов компилятора для операционных систем и компиляторов, которые я чаще всего использую для тестирования.

Для g++ 4.7 в Linux я бы рекомендовал: "-std=c++0x -D_WEBSOCKETPP_CPP11_STL_ -D_WEBSOCKETPP_NO_CPP11_REGEX_ -lboost_regex -lboost_system". Это включает все функции С++ 11, кроме библиотеки (которая сломана/глючит), и вместо нее добавляет версию Boost.

person zaphoyd    schedule 18.03.2013
comment
Спасибо зафойд! Ваша библиотека и поддержка - лучшее, что я когда-либо испытывал! - person ; 18.03.2013
comment
Во-первых, я также хотел бы поблагодарить вас за отличную библиотеку и документацию! Тем не менее, у меня также была эта конкретная проблема. Я собираю чат-сервер с вашей библиотекой и совершенно упустил из виду, что определение D_WEBSOCKETPP_CPP11_STL_ необходимо для использования std::owner_less. Возможно, я недостаточно внимательно прочитал документацию, но было бы неплохо пояснить это на конкретном примере. - person Shump; 09.12.2014

Прочитав документацию, я думаю, вам нужно определить BOOST_ROOT_CPP11 при построении.

Аналогичен BOOST_ROOT, но позволяет связываться с отдельной версией Boost, скомпилированной для C++11 STL.

Я основывался на следующем заголовке

#ifdef _WEBSOCKETPP_CPP11_MEMORY_
    using std::shared_ptr;
    using std::weak_ptr;
    using std::enable_shared_from_this;
    using std::static_pointer_cast;

    typedef std::unique_ptr<unsigned char[]> unique_ptr_uchar_array;
#else
    using boost::shared_ptr;
    using boost::weak_ptr;
    using boost::enable_shared_from_this;
    using boost::static_pointer_cast;

    typedef boost::scoped_array<unsigned char> unique_ptr_uchar_array;
#endif

Что должно использовать std::weak_ptr вместо boost::weak_ptr


Если вы хотите использовать альтернативный контейнер вместо std::set, измените пример, аналогичный этому псевдокоду.

         if (a.type == SUBSCRIBE) {
                boost::unique_lock<boost::mutex> lock(m_connection_lock);
                m_connections.push_back(a.hdl);
            } else if (a.type == UNSUBSCRIBE) {
                boost::unique_lock<boost::mutex> lock(m_connection_lock);
                m_connections.erase(std::remove(m_connections.begin(), m_connections.end(), a.hdl));
            } else if (a.type == MESSAGE) {
                boost::unique_lock<boost::mutex> lock(m_connection_lock);

                con_list::iterator it;
                for (it = m_connections.begin(); it != m_connections.end(); ++it) {
                    m_server.send(*it,a.msg);
                }
            } else {
                // undefined.
            }
        }
    }
private:
    typedef std::deque<connection_hdl> con_list;

Который будет использовать std::deque вместо std::set. Порядок не будет использоваться, но для того, что я могу сказать, это не нужно в этом примере.

person Sam Miller    schedule 15.03.2013