Pracuję nad bardzo dużym projektem iw jednym pliku nagle dostaliśmy błąd kompilacji, w którym kompilator wydaje się myśleć, że nasze wezwanie do winsock.h bind()
to w rzeczywistości połączenie z std::bind()
. Wygląda na to, że gdzieś w pliku włączającym znajduje się fragment kodu using namespace std
. Możemy spróbować ustalić, gdzie te using namespace std
są w użyciu i usunąć je, ale być może jest lepszy sposób to zrobić?std :: bind i winsock.h bind confusion
Odpowiedz
Możesz zmienić swoje połączenia, aby użyć ::bind()
, aby określić globalny obszar nazw.
Tak, to niefortunne. Jak opisano w http://gcc.gnu.org/ml/libstdc++/2011-03/msg00143.html szablon std::bind
jest lepszy mecz, chyba że używasz dokładnie odpowiednie typy argumentów:
Problemem jest to, że funkcja gniazdem bind() ma ten podpis:
int bind(int, const sockaddr*, socklen_t);
więc wywołanie w przykład przy użyciu wskaźnika niestałego stwierdza, że szablon variadicstd :: bind lepiej pasuje. To samo by się stało , jeśli trzeci argument był dowolnym integralnym typem z wyjątkiem socklen_t.
Twój kod będzie działać z GCC bo dodałem zgodny rozszerzenie GCC std::bind
, aby zapobiec tej dwuznaczności, usuwając std::bind
z przeciążeniem ustawiony jeśli pierwszy argument to „gniazdo-like”, które zdefiniowano za pomocą is_integral
i is_enum
. To jednak nie pomaga w innych implementacjach.
Zdejmowanie using namespace std;
jest dobrym pomysłem, ale nie może być całkowicie wystarczające, ponieważ bez zastrzeżeń wywołanie bind()
że dzieje się użyć typu zdefiniowane w przestrzeni nazw std
(takich jak std::size_t
) nadal może znaleźć std::bind
przez odnośnika zależnej argumentów. Odpowiedź Jonathana Pottera jest najlepszym sposobem na uzyskanie właściwej funkcji: zakwalifikuj ją jako ::bind
.
+ 1 do wyjaśnienia, dlaczego. –
przestrzenie nazw są zabawne, prawda? –
Nie, po prostu go usuń. – inf
Usuń 'using namespace std', w przeciwnym razie będziesz mieć ten sam problem kiedyś w przyszłości z inną nazwą. – juanchopanza