Wie zu beheben einen Namen Kollision zwischen einem C++ - namespace und eine Globale Funktion?
wenn ich das definieren eines namespace log
irgendwo und zugänglich zu machen, die im globalen Gültigkeitsbereich, wird dieser clash mit double log(double)
von der standard - cmath
header. Tatsächlich, die meisten Compiler scheinen zu gehen zusammen mit ihm-die meisten Versionen von SunCC, MSVC, GCC-aber GCC 4.1.2 nicht.
Leider scheint es keinen Weg, um diese Mehrdeutigkeit aufzulösen, als using
Erklärungen sind nicht legal für den Namensraum-Bezeichner. Kennen Sie eine Weise, die ich schreiben könnte log::Log
im globalen Namensraum, auch wenn cmath
enthalten ist?
Dank.
BEARBEITEN: Würde jemand wissen, was der C++03 standard hat sich zu diesem Thema zu sagen? Ich hätte gedacht, dass der scope-operator ausreichend disambiguates die Verwendung von log
im code-Beispiel unten.
#include <cmath>
namespace foo
{
namespace log
{
struct Log { };
} //namespace log
} //namespace foo
using namespace foo;
int main()
{
log::Log x;
return 0;
}
//g++ (GCC) 4.1.2 20070115 (SUSE Linux)
//log.cpp: In function `int main()':
//log.cpp:20: error: reference to `log' is ambiguous
///usr/include/bits/mathcalls.h:110: error: candidates are: double log(double)
// log.cpp:7: error: namespace foo::log { }
//log.cpp:20: error: expected `;' before `x'
- Warum nicht einfach schreiben, wie
foo::log::Log
um zu verhindern, dass die ambiguousity? Log
ist nicht das einzige Mitglied derfoo::log
, es gibt viele von diesen. Aber ja, wahrscheinlich werde ich am Ende voll qualifizierende alle diese, wenn es keine andere Möglichkeit gibt.- Möchten Sie vielleicht einen Blick auf diese Antwort.
- Sollte nicht C-Bezeichner importiert durch die
<c****>
Versionen der C-standard-Header befindet sich in derstd
namespace? Ist es ein v4.1 Umsetzung bug (in g++ 4.4 dieser code funktioniert gut) oder ich erinnere mich an diese Sache falsch? - Italia: Diese IDS sind erforderlich, um auch im Internet in den globalen Namensraum. Siehe stackoverflow.com/questions/1524139/... .
- soweit ich das verstehe von diesen standard-angeboten, soweit die Norm betrifft diese Bezeichner müssen in den globalen Namensraum nur, wenn man auch die
<name.h>
C-header, einschließlich<cname>
sollten Sie Sie nur in denstd
namespace. - du hast Recht, ich habe falsch gelesen.
- Ich fand, dass dieser bug sehr ärgerlich, ich konnte den patch
/usr/include/bits/mathcalls.h
aber dann die Datei<cmath>
erwartetlog
werden zum Beispiel in den globalen Namensraum (siehe Zeile 356 in der gcc-stdlib<cmath>
es liestusing ::log;
. Ich Frage mich, ob man mit spielen können alle definierten Makros um korrigieren dieses Verhalten. Übrigens, @MatteoItalia, ich finde das auch in gcc 4.7, also wenn es behoben wurde in 4.4 der Fehler kam wieder.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich würde vorschlagen:
Generell würde ich nicht schreiben
using namespace foo;
da es keinen Punkt gibt, wenn es in derfoo
- namespace, wenn du nicht gehst, es zu benutzen und es belastet die globalen namespace.Sehen, diese Frage im Zusammenhang:
Wie gehen Sie richtig verwenden namespaces in C++?
Obwohl es Ihnen nicht helfen, die Fehler von GCC 4.1.2 ist falsch. Die
log
imlog::Log
kann sich nur auf eine Klasse oder namespace-Namen.Wenn Ihr code wird auch benötigt, um zu kompilieren mit GCC 4.1.2, dann gibt es zwei Möglichkeiten:
foo::log::Log
log
namespace ist nicht ein problem, denn es ist nicht definiert sind, die in dem gleichen Namensraum wie dielog
Funktion. (namespace innerhalbfoo
- namespace-Funktion ist im globalen namespace)cmath
verwendet::log
für einige Grund, um die Globale Reichweite und können sich nicht entscheiden zwischen der Funktion und Ihren Namensraum.Namespaces halten Sie code enthalten, um zu verhindern, dass Verwirrung und Verschmutzung von Funktions-Signaturen.
Hier's eine vollständige und dokumentierte demo von richtige namespace Verwendung:
Ausgabe: