SFINAE um eine freie Funktion aus einem anderen Namensraum zu testen

8

Ich habe versucht, einen Hack zu erstellen, um zu testen, ob std::isnan ohne spezielle Gehäuse-Compiler im Präprozessor definiert ist, und kam zu dem Ergebnis, das ich gut verarbeitet habe.

%Vor%

Stellt sich heraus es erkennt es nicht . Ich weiß sicher, dass std::isnan auf ideone definiert ist, weil ich das manuell getestet habe.

Und wenn ich die markierte Zeile auskommentiere , funktioniert es.

Was fehlt mir hier? Was erklärt dieses Verhalten?

    
R. Martinho Fernandes 06.01.2012, 10:57
quelle

2 Antworten

7

Die Sache ist, dass die using-Direktive dem aktuellen Namespace keine Member hinzufügt, daher könnten die std:: -Member immer noch durch Deklarationen in diesem Namespace verborgen werden.

using std::isnan verhält sich stattdessen so, als ob die Member des importierten Namespace zum Namespace hinzugefügt würden, der sowohl den use -location als auch den importierten Namespace enthält. Die using-Deklaration ist eine normale Deklaration im Namespace und kann daher mit den folgenden Deklarationen an der Überladungsauflösung teilnehmen.

Wie jedoch in den Kommentaren erwähnt, würde dies zu einem Fehler führen, wenn die Funktion nicht existiert. Um das zu umgehen, müssen Sie es aus Ihrem detail:: Namespace entfernen und dann . Das sollte funktionieren, weil die importierte Definition auf der gleichen Ebene wie die dummy Überladung wäre. Sie können die Überladung auf den globalen Namespace anwenden, oder Sie können einen zusätzlichen Namespace (im globalen Namespace) erstellen und beide importieren .

    
jpalecek 06.01.2012, 11:04
quelle
1

Ich habe dieses Problem für die Gruppe der threadsicheren POSIX-APIs gelöst, die nicht thread-sichere Standardfunktionen ersetzen: C ++ 11 Alternative zu localtime_r . Dieser Code erkennt, ob eine API im globalen Namespace definiert ist und, falls sie nicht existiert, eine benutzerdefinierte Problemumgehung auswählt.

    
Potatoswatter 06.01.2012 14:33
quelle

Tags und Links