2013-02-21 3 views
0

Im пытается скомпилировать проект с использованием boost, привязка asio :: io_service для boost :: thread и Im получение ошибок, которые я не знаю, как разрешить Использование: IBM XL C/C++ для AIX, V11.1 (5724-X13) Версия: 11.01.0000.0006 (AIX 7,1)Boost bind AIX xlc io_service run

"/home/clag/projects/tomas/include/boost/asio/detail/posix_fd_set_adapter.hpp", line 33.30: 1540-0198 (W) The omitted keyword "private" is assumed for base class "noncopyable". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.46: 1540-0219 (S) The call to "boost::bind" has no best match. 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.58: 1540-1229 (I) Argument number 1 is an rvalue of type "overloaded function: boost::asio::io_service::run". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.100: 1540-1229 (I) Argument number 2 is an rvalue of type "const boost::reference_wrapper<const boost::asio::io_service>". 
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 30.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)() const, reference_wrapper<const boost::asio::io_service>)". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.58: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)() const" uses the resolved overloaded function "size_t boost::asio::io_service::run()". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.100: 1540-1231 (I) The conversion from argument number 2 to "boost::reference_wrapper<const boost::asio::io_service>" uses "the identity conversion". 
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 20.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)(), reference_wrapper<const boost::asio::io_service>)". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.58: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)()" uses the resolved overloaded function "size_t boost::asio::io_service::run()". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.100: 1540-1231 (I) The conversion from argument number 2 to "boost::reference_wrapper<const boost::asio::io_service>" uses "the identity conversion". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.35: 1540-0219 (S) The call to "boost::bind" has no best match. 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.47: 1540-1229 (I) Argument number 1 is an rvalue of type "overloaded function: boost::asio::io_service::run". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.98: 1540-1229 (I) Argument number 2 is an rvalue of type "boost::asio::io_service *". 
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 30.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)() const, io_service *)". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.47: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)() const" uses the resolved overloaded function "size_t boost::asio::io_service::run()". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.98: 1540-1231 (I) The conversion from argument number 2 to "boost::asio::io_service *" uses "the identity conversion". 
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 20.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)(), io_service *)". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.47: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)()" uses the resolved overloaded function "size_t boost::asio::io_service::run()". 
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.98: 1540-1231 (I) The conversion from argument number 2 to "boost::asio::io_service *" uses "the identity conversion". 
    "/home/clag/projects/tomas/include/boost/asio/impl/write.hpp", line 276.7: 1540-0198 (W) The omitted keyword "private" is assumed for base class "detail::base_from_completion_cond<CompletionCondition>". 
    "/home/clag/projects/tomas/include/boost/asio/impl/write.hpp", line 276.7: 1540-0198 (W) The omitted keyword "private" is assumed for base class "detail::base_from_completion_cond>boost::asio::detail::transfer_all_t>" 

код, который вызывает ошибку:

acceptor_thread_.reset(new boost::thread(boost::bind(&boost::asio::io_service::run, boost::cref(*accept_io_service_)))); 
    for (int i = 0; i < agent_config_.threads(); i++) { 
     thread_group_.create_thread(boost::bind(&boost::asio::io_service::run, work_io_service_.get())); 
    } 

Определение:

boost::shared_ptr<boost::asio::io_service> accept_io_service_; 
    boost::shared_ptr<boost::thread> acceptor_thread_; 
    boost::shared_ptr<boost::asio::io_service> work_io_service_; 
    boost::thread_group thread_group_; 

Как раз упомянуть, это, вероятно, будет только некоторым вариантом флага, но я не могу найти его где-нибудь Поскольку тот же код отлично компилируется на Linux (GCC), HP-UX (aCC) и Windows (MSVC).

Thx за помощью

ответ

2

Быстрый поиск Google предполагают, что AIX имел проблемы с разрешением перегрузки, особенно когда шаблоны участвуют. Таким образом, возможно, стоит попробовать разные подходы к уменьшению количества разрешений перегрузки, которые должны произойти.

Например, boost::mem_fn() можно использовать вместо boost::bind().

std::size_t (io_service::*run)() = &io_service::run; 
boost::thread t(boost::mem_fn(run), io_service); 

Кроме того, если у компилятора все еще возникают проблемы с перегрузкой, рассмотрим возможность написания простого функтора. Единственным требованием для конструктора boost::thread() является то, что аргумент func является копируемым, а func() должен быть допустимым выражением.

struct service_runner 
{ 
    explicit service_runner(boost::shared_ptr<boost::asio::io_service> io_service) 
    : io_service(io_service) 
    {} 
    std::size_t operator()() { return io_service->run(); } 
    boost::shared_ptr<boost::asio::io_service> io_service; 
}; 

... 

boost::thread t((service_runner(io_service))); 

Других принять во внимание:

  • Предпочитает компиляции соответствующего кода, а не с помощью флагов компилятора, чтобы несоответствующие код для компиляции. В этом конкретном случае io_service::run() является функцией, не являющейся константой, но связанный с ней аргумент аргумента accept_io_service передается как постоянная ссылка через boost::cref(). Должны быть добавлены флаги компилятора, такие как gcc -fpermissive, чтобы можно было компилировать несоответствующий код. Будьте очень осторожны в использовании этих параметров, поскольку они могут маскировать серьезные проблемы.
  • Рассмотрите возможность передачи boost::shared_ptr в качестве дескриптора экземпляра для вызовов привязки. Это сохранит io_service до тех пор, пока поток все еще работает. В противном случае io_service может быть удален, пока поток по-прежнему обрабатывает свой цикл событий, что приводит к высокой вероятности вызова неопределенного поведения.
+0

Благодарим вас за обертку 'service runner', она работает как шарм. Первый метод с использованием 'boost :: mem_fn()' did not work out the 'Определитель" accept_io_service_ "не определен в текущей области.', Что является странным, потому что это переменная-член. Чтобы прокомментировать другие моменты, 'boost :: cref()' был просто тестом, который я нашел где-то на форумах, на других платформах я использую 'boost :: shared_ptr', как я предполагал. Еще раз спасибо за большое предложение. – Pinker

+0

Еще один вопрос: в AIX 6.1 (xlC_r V9.0) он не компилируется, Im получает '/include/boost/thread/detail/thread.hpp", строка 62.17: 1540-0204 (S) Выражение типа " boost :: thread * "не должен сопровождаться ошибкой operator call().' при использовании 'service_runner'. Может быть, вы можете объяснить мне лучшее первое предложенное решение с помощью' mem_fn'? Поскольку я не понимаю, что такое 'std :: size_t (io_service :: * run)() = & io_service :: run; 'statement. Спасибо – Pinker

+0

@Pinker: Мне нужно было бы, чтобы использование могло определить проблему, поскольку я не знаком с AIX. объявляет 'run' как указатель на функцию члена' io_service', которая возвращает 'std :: size_t' и не принимает никаких аргументов. Затем он присваивает адрес функции io_service :: run()' указателю на функцию-член. цель должна быть явной, не позволяя компилятору вывести подпись в вызове 'bind' перегруженного [' io_service :: run() ') (http://www.boost.org/doc/lib с/1_53_0/DOC/HTML/boost_asio/ссылка/io_service/run.html). –

1

Любопытно, используете ли вы патч библиотеки IBM boost для используемого вами компилятора? http://www-01.ibm.com/support/docview.wss?uid=swg27006911

+0

Нет, так как его дата 3 года назад, используя boost 1.40.0 (это 13 выпусков назад), я ожидал, что большинство этих обходных решений уже будут в ускоренных библиотеках, а также ожидалось много ошибок, исправленных в этих 13 выпусках (хотя Im использует boost 1.49.0) – Pinker

+0

Pinker, IMHO вы слишком оптимистичны , Я предпочитаю проверять каждую версию самостоятельно, используя тесты регрессии. – vond

0

Глядя на сообщения для 4 возможных кандидатов пытались, различия, кажется, быть константной связаны

No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)() const, reference_wrapper<const boost::asio::io_service 
>)". 
No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)(), reference_wrapper<const boost::asio::io_service>)". 
No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)() const, io_service *)". 
No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)(), io_service *)". 

Поскольку вы используете V11.1 компилятор, есть несколько исправлений не включена по умолчанию, которые вы можете попробовать использовать следующие варианты

-qxflag = EnableIssue214PartialOrdering Это позволит несколько исправлений, связанных с эмиссией ++ ядра языка C 214

-qxflag = FunctionCVTmplArgDeduction2011 Это позволяет некоторым C++ 2011 уточнений к аргументу дедукции

Эти изменения по умолчанию на V12.1 компилятором, но не на V11.1 компилятором

0

Я добавляю additinal ответ, если кто-то спотыкается U pon эта проблема вообще. Поскольку я выяснил, что это связано с тем, что компилятор не может решить, какую функцию использовать, если функции имеют одно и то же имя, но разные параметры.

Пример:

void test(int a); 
void test(int a, int b); 

не будет работать, и будет вызывать подобную ошибку, как указано выше.
Но изменение названия вроде этого:

void test(int a); 
void test2(int a, int b); 

... будет работать прекрасно.

Это, безусловно, меньше накладных решений, чем создание оберток (как я сам делал до наблюдения за этим).

Надеюсь, что кто-то найдет это полезным.

Смежные вопросы