|
You last visited: Today at 01:56
Advertisement
Warum man using namespace std; nicht verwenden sollte
Discussion on Warum man using namespace std; nicht verwenden sollte within the C/C++ forum part of the Coders Den category.
10/13/2013, 03:05
|
#1
|
elite*gold: 51
Join Date: Nov 2008
Posts: 486
Received Thanks: 69
|
Warum man using namespace std; nicht verwenden sollte
Guten Abend Dev's!
Ich habe bei meiner Socketverbindung ein kleines Problem und zwar kriege ich bei der bind Funktion seit neusten den Fehler: C2440, ich weiß leider nicht, was ich verändert habe, was den Fehler auslösen könnte.
Aufgrunddessen muss ich euch leider damit belästigen
Quellcode (nur das wichtigste, der Rest wurde entfernt): - Zeile 46
Fehler: C2440
Code:
error C2440: '=': 'std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' kann nicht in 'long' konvertiert werden
with
[
_Forced=false,
_Ret=void,
_Fun=SOCKET &,
_V0_t=sockaddr *,
_V1_t=int &,
_V2_t=std::_Nil,
_V3_t=std::_Nil,
_V4_t=std::_Nil,
_V5_t=std::_Nil,
<unnamed-symbol>=std::_Nil
]
Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
P.S Vorher hat es prima funktioniert.
LG
|
|
|
10/13/2013, 03:08
|
#2
|
elite*gold: 0
Join Date: Aug 2011
Posts: 364
Received Thanks: 29
|
Also du hast da was verändert und dannach bekamst du die Fehlermeldung bzw den "Error"?
MFG
|
|
|
10/13/2013, 03:10
|
#3
|
elite*gold: 51
Join Date: Nov 2008
Posts: 486
Received Thanks: 69
|
Ja, ich habe beispielsweise die unübersichtlichen If-Anweisungen durch Switch-Anweisungen ersetzt, Threads hinzugefügt usw.
|
|
|
10/13/2013, 04:50
|
#4
|
elite*gold: 724
Join Date: Mar 2011
Posts: 10,480
Received Thanks: 3,319
|
Hast du "using namespace std;" in deinem Code? Du rufst in deinem Code die std::bind Funktion auf und nicht die Winsock-Funktion.
Um das zu lösen, kannst du :: vor deinen Aufruf schreiben, um den globalen Namespace zu verwenden oder du entfernst dein using namespace, was wohl die bessere Lösung wäre.
|
|
|
10/13/2013, 12:41
|
#5
|
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
|
Quote:
Originally Posted by snow911
Hast du "using namespace std;" in deinem Code? Du rufst in deinem Code die std::bind Funktion auf und nicht die Winsock-Funktion.
Um das zu lösen, kannst du :: vor deinen Aufruf schreiben, um den globalen Namespace zu verwenden oder du entfernst dein using namespace, was wohl die bessere Lösung wäre.
|
Es wird in der Tat versucht, std::bind aufgerufen, wenn die Fehlermeldung stimmt. Dann verwendest du auch VS 2010 oder VS 2012.
|
|
|
10/13/2013, 13:02
|
#6
|
elite*gold: 51
Join Date: Nov 2008
Posts: 486
Received Thanks: 69
|
Quote:
Originally Posted by Tasiro
Quote:
Originally Posted by snow911
Hast du "using namespace std;" in deinem Code? Du rufst in deinem Code die std::bind Funktion auf und nicht die Winsock-Funktion.
Um das zu lösen, kannst du :: vor deinen Aufruf schreiben, um den globalen Namespace zu verwenden oder du entfernst dein using namespace, was wohl die bessere Lösung wäre.
|
Es wird in der Tat versucht, std::bind aufgerufen, wenn die Fehlermeldung stimmt. Dann verwendest du auch VS 2010 oder VS 2012.
|
Ich verwende VS2012. Ein using namespace std; ist ebenfalls so gut wie immer vorhanden, derzeit auch. Wie wandel ich nun das bind() wieder als Winsock Funktion um?
Ich kann mir garnicht erklären, was ich verändert habe, das den Fehler auslöst
P.S Mein Header sieht wie folgt aus
Code:
#pragma comment(lib, "ws2_32.lib")
#include <cstdio>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include <thread>
using namespace std;
char recvbuf[256];
char sendbuf[256];
[...]
int main()
{
}
LG
|
|
|
10/13/2013, 13:05
|
#7
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
|
Streich das using namespace std;
Die faule und schnellere Variante wäre ::bind
|
|
|
10/13/2013, 13:48
|
#8
|
elite*gold: 51
Join Date: Nov 2008
Posts: 486
Received Thanks: 69
|
Quote:
Originally Posted by MrSm!th
Streich das using namespace std;
Die faule und schnellere Variante wäre ::bind
|
Aber warum überschreibt sozusagen nun std die Winsock-Funktion? Außerdem bekomme ich ein C2198 auf meine Threadfunktion, wenn ich eine deiner Lösugsvorschläge ausprobiere.
Zeile
Code:
while(1)
{
// Threads generieren
std::thread t0(getuser, res, slisten, clientinfo, clientinfolen),
t1(msgtrans, res, client),
t2(sendmsg, res);
// Einkommende Verbindungen verwalten
t0.join();
// Nachrichten auswerten und weiterleiten
res = recv(client, recvbuf, 256, 0);
t1.join();
// Server Nachrichten senden
res = send(client, sendbuf, strlen(sendbuf), 0);
t2.join();
}
Fehler (C2198)
Code:
1> Main.cpp
1>c:\program files (x86)\microsoft visual studio\vc\include\functional(1152): error C2198: "void (__cdecl *)(long,SOCKET,SOCKET,sockaddr_in,int)": Nicht genügend Argumente für Aufruf.
1> c:\program files (x86)\microsoft visual studio\vc\include\functional(1152): Bei der Kompilierung der Klassen-template der void std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>::operator ()(void)-Memberfunktion
1> with
1> [
1> _Forced=true,
1> _Ret=void,
1> _Fun=void (__cdecl *const )(long,SOCKET,SOCKET,sockaddr_in,int),
1> _V0_t=long &,
1> _V1_t=SOCKET &,
1> _V2_t=sockaddr_in &,
1> _V3_t=int &,
1> _V4_t=std::_Nil,
1> _V5_t=std::_Nil,
1> <unnamed-symbol>=std::_Nil
1> ]
1> c:\program files (x86)\microsoft visual studio\vc\include\thr\xthread(195): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "void std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>::operator ()(void)".
1> with
1> [
1> _Forced=true,
1> _Ret=void,
1> _Fun=void (__cdecl *const )(long,SOCKET,SOCKET,sockaddr_in,int),
1> _V0_t=long &,
1> _V1_t=SOCKET &,
1> _V2_t=sockaddr_in &,
1> _V3_t=int &,
1> _V4_t=std::_Nil,
1> _V5_t=std::_Nil,
1> <unnamed-symbol>=std::_Nil
1> ]
1> c:\program files (x86)\microsoft visual studio\vc\include\thread(52): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>".
1> with
1> [
1> _Forced=true,
1> _Ret=void,
1> _Fun=void (__cdecl *const )(long,SOCKET,SOCKET,sockaddr_in,int),
1> _V0_t=long &,
1> _V1_t=SOCKET &,
1> _V2_t=sockaddr_in &,
1> _V3_t=int &,
1> _V4_t=std::_Nil,
1> _V5_t=std::_Nil,
1> <unnamed-symbol>=std::_Nil
1> ]
1> c:\users\leon\documents\visual studio 2012\projects\winsock tcp server\winsock tcp server\main.cpp(168): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "std::thread::thread<void(__cdecl *)(long,SOCKET,SOCKET,sockaddr_in,int),long&,SOCKET&,sockaddr_in&,int&>(_Fn,_V0_t,_V1_t,_V2_t,_V3_t)".
1> with
1> [
1> _Fn=void (__cdecl *)(long,SOCKET,SOCKET,sockaddr_in,int),
1> _V0_t=long &,
1> _V1_t=SOCKET &,
1> _V2_t=sockaddr_in &,
1> _V3_t=int &
1> ]
========== Erstellen: 0 erfolgreich, 1 fehlerhaft, 0 aktuell, 0 übersprungen ==========
LG und vielen Dank für eure tatkräftige Unterstützung
|
|
|
10/13/2013, 14:35
|
#9
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
|
Weil sie nunmal gleich heißen. Woher soll der Compiler bitte wissen, welches bind du meinst? Deshalb nimmt er das aus dem Namensraum, den du ihm vorgibst, was du mit using namespace std; getan hast.
Deshalb ist using namespace im globalen Kontext böse.
Wie sieht denn jetzt der Code aus, in dem vorher der Fehler auftrat? Und wie steht der Code mit den Threads damit in Verbindung? Wo wird der neue Fehler genau geworfen?
|
|
|
10/13/2013, 14:37
|
#10
|
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
|
std::bind überschreibt ::bind nicht, aber std::bind lässt einfach alles als Argument zu. Argumente sind:
SOCKET, sockaddr*, int
::bind erwartet:
SOCKET, const sockaddr*, int
std::bind erwartet:
Fn&&, Arg1&&, Arg2&&
Damit ist std::bind einfach die bessere Wahl. Da muss nichts konvertiert werden. Also wird die Templatefunktion std::bind<SOCKET, sockaddr*, int> gewählt.
Das hat nichts damit zu tun, dass mit using namespace std; irgendein Namensraum "vorgegeben" wird, sondern damit, dass std::bind und ::bind beide als bind ansprechbar sind. Aber das sind sie nur, weil du using namespace std; verwendetest. Du solltest auf using namespace generell verzichten.
Mehr zu Templates und Überladungen: .
|
|
|
10/13/2013, 14:44
|
#11
|
elite*gold: 0
Join Date: Jun 2008
Posts: 451
Received Thanks: 410
|
hast du winsock2.h includiert oder winsock.h?
|
|
|
10/13/2013, 15:33
|
#12
|
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
|
Der Compilerfehler C2198 entsteht, weil du im Kontruktoraufruf für t0 ein Argument zu wenig übergibst. Die Funktionssignatur von getuser sieht etwa so aus:
void getuser (long, SOCKET, SOCKET, sockaddr_int, int)
Du aber übergibst dem Konstruktor als Argumente für getuser:
long, SOCKET, sockaddr_in, int
Das ist ein SOCKET zu wenig. Kein Wunder, dass sich der Compiler beschwert.
Deine Logik leuchtet mir nicht ein... zuerst startest du drei Threads, welche dann sofort getuser, msgtrans und sendmsg ausführen;
dann wartest du, bis getuser zurückkehrt;
dann rufst du die Funktion recv auf und wartest danach, bis msgtrans zurückkehrt;
dann rufst du die Funktion send auf und wartest danach, bis sendmsg zurückkehrt.
Warum?
Du solltest dir std::async und std::future ansehen, damit geht das viel besser.
|
|
|
10/13/2013, 15:59
|
#13
|
elite*gold: 51
Join Date: Nov 2008
Posts: 486
Received Thanks: 69
|
Quote:
Originally Posted by MrSm!th
Weil sie nunmal gleich heißen. Woher soll der Compiler bitte wissen, welches bind du meinst? Deshalb nimmt er das aus dem Namensraum, den du ihm vorgibst, was du mit using namespace std; getan hast.
Deshalb ist using namespace im globalen Kontext böse.
Wie sieht denn jetzt der Code aus, in dem vorher der Fehler auftrat? Und wie steht der Code mit den Threads damit in Verbindung? Wo wird der neue Fehler genau geworfen?
|
Der Fehler wird bei der Generierung der Threads geworfen, sprich
Code:
thread t0(getuser, res, slisten, clientinfo, clientinfolen),
t1(msgtrans, res, client),
t2(sendmsg, res);
|
|
|
10/13/2013, 17:55
|
#14
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
|
Laut Fehlermeldung hat dein Funktionsaufruf zu wenig Argumente. Was mir auffällt:
Dort steht, der Prototyp hat 2 Socket Parameter.
Quote:
Originally Posted by Tasiro
std::bind überschreibt ::bind nicht, aber std::bind lässt einfach alles als Argument zu. Argumente sind:
SOCKET, sockaddr*, int
::bind erwartet:
SOCKET, const sockaddr*, int
std::bind erwartet:
Fn&&, Arg1&&, Arg2&&
Damit ist std::bind einfach die bessere Wahl. Da muss nichts konvertiert werden. Also wird die Templatefunktion std::bind gewählt.
Das hat nichts damit zu tun, dass mit using namespace std; irgendein Namensraum "vorgegeben" wird, sondern damit, dass std::bind und ::bind beide als bind ansprechbar sind. Aber das sind sie nur, weil du using namespace std; verwendetest. Du solltest auf using namespace generell verzichten.
Mehr zu Templates und Überladungen: .
|
Das meinte ich damit auch, von überschreiben habe ich nicht gesprochen.
Letztendlich wird dadurch std::bind zu einer Überladung.
Entschuldige die unklare Ausdrucksweise.
|
|
|
10/13/2013, 18:32
|
#15
|
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
|
Quote:
Originally Posted by MrSm!th
Das meinte ich damit auch, von überschreiben habe ich nicht gesprochen.
|
Das war gar nicht an dich gerichtet, Zissy sprach davon.
Quote:
Originally Posted by Zissy
Aber warum überschreibt sozusagen nun std die Winsock-Funktion?
|
|
|
|
|
|
Similar Threads
|
Warum sollte man nicht die Lane pushen in 3v3? / Range vs Nah
10/02/2013 - League of Legends - 18 Replies
Ich sehe z.B wie ein Challenge oder auch andere Leute immer die Minions ie Arbeit machen lassen, und nur lasthitten, ich klopp da mit meinem aa noch drauf und versuch dann zu lasthitten.
Warum sollte man das nicht tun.
2. Frage : Ich spiele Aatrox und hab als Gegner Catlyn oder sonst nen AD-Fernchamp, wie sollte ich am besten spielen, sie kann mich immer von der Ferne in Schach halten und mich hitten, ich aber sie nicht.
|
BF3 - Warum Kann ich Auf Manchen Maps die AK oder die M4A1 nicht verwenden?
11/10/2011 - Battlefield - 9 Replies
warum kann ich eig. auf manchen maps die m4a1 oder ak nich bentuzen? z.b auf der map mit dem zug kann ich die ak nich nehmen und auf anderen kann ich die m4a1 nich nehmen-.-. weis jemand warum das nich geht?
oder is des bei jedem so?
danke für antworten :)
|
Warum man im Internet nicht nach Hilfe fragen sollte...
10/14/2008 - Off Topic - 9 Replies
click me =)
|
All times are GMT +2. The time now is 01:56.
|
|