Problem mit lokalem using namespace in Funktionen



  • Hallo zusammen,

    ich habe in einem Namespace eine Standardfunktion (operator<<) überladen und in einem darin verschachtelten Namespace nochmals.

    #include <iostream>
    #include <string>
    
    namespace test {
    	struct myClass {
    		std::string _name;
    
    		explicit myClass(std::string name) : _name{ name } {}
    		void print(std::ostream& os) const { os << _name; }
    	};
    
    	std::ostream& operator<<(std::ostream& os, const myClass& mC) {
    		mC.print(os);	return os;
    	}
    
    	namespace debug {
    		std::ostream& operator<<(std::ostream& os, const myClass& mC) {
    			os << "debug: ";
    			mC.print(os);
    			return os;
    		}
    	}
    }
    
    test::myClass mc{"Kai"};
    
    void run() {
    	using namespace test;
    	std::cout << mc << std::endl;
    }
    
    void runDebug() {
    	using namespace test::debug;
    	std::cout << mc << std::endl;		// das erzeugt den Fehler
    	// test::debug::operator<<(std::cout, mc) << std::endl;		// so klappt das
    
    }
    
    int main() {
    	run();
    	runDebug();
    	
    	return 0;
    }
    

    Der Compiler (MS VC++ 2019) zeigt mir den Fehler

    "Operator <<" ist mehrdeutig
    

    Der scheint das using aus der Funktion "run" global zu nehmen.

    Egal wo man hin googelt, überall heißt es "funktioniert so". Ich muss was am Auge haben. Kann mir vielleicht einer sagen, wo sich mein Fehler versteckt - ausser der vorm Bildschirm?

    Danke
    und viele Grüße
    Kai



  • Kommentier mal die beiden using - Zeilen aus.
    Merkste was?



  • Wegen ADL findet der Compiler auf jeden Fall immer die Operatorüberladung im gleichen Namensbereich (bei dir also in test), auch ohne Angabe von using namespace test.
    Und mittels using namespace test:debug gibst du dem Compiler eine 2. Operatorüberladung mit gleicher Signatur, und daher gibt es die Fehlermeldung bzgl. Mehrdeutigkeit.

    Alternative wäre auch die erste Operatorüberladung in einem eigenen Namensbereich zu erzeugen: ideone-Code



  • Ja, der scheint das direkt aus der Definition des Namespace zu nehmen? Keine Ahnung; stehe mir da gerade auf dem Schlauch, warum die Definition von test::operator<< global genommen wird.



  • using test::debug::operator<<;
    

    sollte gehen.



  • Nein, das geht auch nicht: Ideone-Code
    Denn ohne diese Zeile wird ja wegen ADL einfach auf den in test definierten operator << zugegriffen: Ideone-Code ohne using, d.h. 2x "Kai" ausgegeben.



  • @Th69 Ah, richtig.
    Gut, das ist dann ein Fall von "geht so einfach nicht".


Log in to reply