2013-03-06 26 views
5

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

+0

przestrzenie nazw są zabawne, prawda? –

+4

Nie, po prostu go usuń. – inf

+2

Usuń 'using namespace std', w przeciwnym razie będziesz mieć ten sam problem kiedyś w przyszłości z inną nazwą. – juanchopanza

Odpowiedz

15

Możesz zmienić swoje połączenia, aby użyć ::bind(), aby określić globalny obszar nazw.

7

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.

+0

+ 1 do wyjaśnienia, dlaczego. –