Ошибка «Не удалось вывести аргумент шаблона» при использовании вызова Winsock bind () с Boost - PullRequest
2 голосов
/ 17 марта 2010

Я довольно новичок в C ++, и, вероятно, у меня над головой, но так оно и есть.

Я работаю с довольно крупным проектом Win32 C ++, который использует Winsock для сетевых коммуникаций. Я пытаюсь преобразовать кучу управления потоками в повышение, но как только я добавлю ссылки на библиотеки повышения и прочее, я получаю около 30 ошибок в этой конкретной строке кода:

bind(mLocalSocketFd, (struct sockaddr *) &localServerAddress, sizeof(localServerAddress));

Ошибки включают в себя такие вещи, как:

error C2602: 'std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>::_Type' is not a member of a base class of 'std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>'
error C2868: 'std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>::_Type' : illegal syntax for using-declaration; expected qualified-name
error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'std::tr1::_Bind_fty<_Fty,_Ret,_BindN>' 
error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'std::tr1::_Bind_fty<_Fty,_Ret,_BindN>'

Я предполагаю, что каким-то образом мне удалось сказать этому конкретному файлу («NetServer.cpp») использовать улучшенную версию bind (), но я не могу понять, где это происходит. Единственная часть надстройки, которую я использую, - это boost / thread.hpp, и я не использую пространство имен где-либо в NetServer.cpp или в заголовочных файлах, на которые он ссылается.

Есть предложения относительно того, что я делаю неправильно, или как это устранить? Очевидно, это какая-то глупая новичок, но я не могу понять это.

Ответы [ 3 ]

3 голосов
/ 17 марта 2010

Есть функция Boost, называемая bind () , которая совершенно отличается от bind () Winsock *) 1004 *.

У вас есть два варианта, если вам нужны обе функции, доступные в данном модуле:

  1. Не говорите "используя усиление пространства имен". Вместо этого явно определите использование Boost в вашем коде. Я предпочитаю эту опцию, так как Boost является сторонней библиотекой, и ее короткие имена могут конфликтовать как с другими сторонними библиотеками, так и с будущими версиями C ++, которые будут использовать функции Boost. Время от времени я буду говорить «используя усиление пространства имен» в пределах одной функции, если она содержит несколько применений Boost.

  2. Явно квалифицируйте использование глобальной привязки Winsock ():

    ::bind(mLocalSocketFd, ...

2 голосов
/ 16 сентября 2011

Как вы можете видеть из загадочного сообщения об ошибке MSVC, ваш bind вызов переходит на std::tr1::bind.

Итак, вероятно, вы используете namespace std;.

как @WarrenЯнг указал, что ::bind перенаправит ваш звонок на неквалифицированный идентификатор bind, который в данном случае будет WinSock.

1 голос
/ 18 декабря 2012

Я только что столкнулся с той же проблемой, и нашел официальный ответ Microsoft здесь: http://connect.microsoft.com/VisualStudio/feedback/details/500364/how-to-avoid-conflicts-between-tr1-bind-and-winsock-bind-function

Короткая версия : Даже если вы не вызываете пространство имен Boost, я думаю, у вас где-то есть using namespace std, и, поскольку я предполагаю, что вы используете VS2010, оно имеет расширение tr1, поэтому using namespace std действует как using namespace boost для функции bind () с VS2010.

Если у вас когда-нибудь что-нибудь получится, позвоните заранее using namespace std, тогда

вы делаете все имена в пространстве имен std доступными для неквалифицированных поиск имени. Следовательно, как Winsock's bind (), так и s bind () учитываются при разрешении перегрузки, и потому что bind () - это шаблон, он обычно побеждает, но не скомпилировать позже.

Решение

Чтобы это исправить, вызовите :: bind (), когда вы хотите bind () Winsock, и std :: bind (), если вам когда-либо понадобится bind (). Когда вы звоните :: bind (), вы просите компилятор посмотреть в глобальном пространстве имен только.

Или, альтернативно, не использовать стандартное пространство имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...