Frage zum Name-Lookup
-
Hallo,
ich habe eine Frage zum Name-Lookup, bzw. ob/warum folgender Code falsch ist:
int f( int) { return int(); } namespace N { class A {}; A g( int(*)(int), A) { return A(); } int h( int i){ return f(i); } A f( A a) { return g( f, a); } // compiliert nicht : cannot convert A(*)(A) to int(*)(int) A f( A a) { return g( h, a); } // compiliert }Tritt auch mit dem Comeau-Onlinecompiler so auf, von daher denke ich, dass es kein Artefakt meines Compilers ist (KAI C++).
Warum wird in ersterer Variante die global sichtbare Funktion f nicht berücksichtigt? Und wie kann ich dafür sorgen (möglichst ohne den Schritt über eine Stub-Funktion h), dass auch die global sichtbare Funktion f zur Überladungsauflösung herangezogen wird? Dabei ist anzumerken, dass ::f nicht verwendet werden kann, weil die Funktion u.U. aus einem anderen namespace kommt und nur per using global sichtbar ist.
-
Deine Funktion heisst doch schon f. Du erreichst die globale dann mit ::f.
-
7H3 N4C3R schrieb:
Dabei ist anzumerken, dass ::f nicht verwendet werden kann, weil die Funktion u.U. aus einem anderen namespace kommt und nur per using global sichtbar ist.

Ich weiß, dass die Funktion f heißt. Soll sie auch. Wieso wird die globale Funktion nicht zur Überladungsauflösung herangezogen?
-
Weil es innerhalb eines Namespaces (auch für die Suche) nur ein f geben kann.
Ansonsten gib doch den externen Namespace an (was du wahrscheinlich nicht willst?).Und was passiert, wenn du
namespace N { using ::f; // <- hier angeben ... }schreibst?
-
Dann wird möglicherweise f nicht gefunden.
Das konkrete Problem ist, diverse mathematische Funktionen für Matrizen zu überladen - z.B. Matrix tan( Matrix). Je nach Compiler etc. steht tan aber mal im globalen Namensraum und mal in std:: mit einem using global sichtbar gemacht. Die Hauptmotivation ist Plattform-Unabhängigkeit. Das Programm muss jetzt schon unter 3 Plattformen (mit insgesamt 6 verschiedenen Compilern) laufen und es werden tendenziell mehr. Da ist eine Anpassung für jede Plattform einfach kontraproduktiv.
Wenn ich es also richtig verstehe, wird der globale Namensraum durchsucht, wenn im aktuellen Namensraum kein f gefunden werden konnte? Falls schon eines gefunden wurde, wird nicht gesucht? Hätte jemand vielleicht den entsprechenden Absatz im Standard parat? Ich bin zwar schon am Suchen, habe die passende Stelle aber noch nicht.
Edit: Letzteres habe ich selbst gefunden. 3.3.7 Clause 1
-
So, nach etwas rätseln habe ich dann die Lösung gefunden - u.a. auch dafür, dass ich z.B. tan auch nicht mit ::tan referenzieren konnte (abgesehen vom Namespace-Lookup-Problem).
typedef extern "C" { int (* Foo)( int); }und
typedef int(* Bar)( int);sind verschiedene Typen, die nicht zueinander kompatibel sind (und auf einem standardkonformen Compiler auch nicht implizit ineinander konvertierbar). tan kann wohl auch extern "C" sein. Lösung ist, eine zusätzliche Funktion A g(Foo, A) bereitzustellen.
-
7H3 N4C3R schrieb:
Wenn ich es also richtig verstehe, wird der globale Namensraum durchsucht, wenn im aktuellen Namensraum kein f gefunden werden konnte? Falls schon eines gefunden wurde, wird nicht gesucht? Hätte jemand vielleicht den entsprechenden Absatz im Standard parat? Ich bin zwar schon am Suchen, habe die passende Stelle aber noch nicht.
Edit: Letzteres habe ich selbst gefunden. 3.3.7 Clause 1
am besten dürfte 3.4.1/1 i.V.m. 3.4.1/6 (mit beispiel) passen.
Das konkrete Problem ist, diverse mathematische Funktionen für Matrizen zu überladen - z.B. Matrix tan( Matrix).
hier bietet sich ADL an (Koenig-Lookup).
-
camper schrieb:
am besten dürfte 3.4.1/1 i.V.m. 3.4.1/6 (mit beispiel) passen.
hier bietet sich ADL an (Koenig-Lookup).
Danke.
Werde mir letzteres mal genauer anschauen...