Mehrdeutigkeit



  • Hi,

    Wieso heißt es hier, dass eine mehrdeutigkeit vorliegt?:

    #include <iostream>
    using namespace std;
    
    namespace einBereich {
    	// Deklaration im Namensbereich einBereich
    	int iwert = 11;
    }
    
    // globale Deklaration
    int iwert = 22;
    
    int main(void) {
    	using namespace einBereich;
    
    	// lokale Deklaration
    	// int iwert = 33;
    
    	iwert = 5;    // Mehrdeutigkeit
    
    	return EXIT_SUCCESS;
    }
    


  • Ich werde das Gefühl nicht los, dass du ein Troll bist. Welcher Variable soll denn nun der Wert 5 zugewiesen werden?



  • Es ist mehrdeutig, weil der Compiler nicht weiß, ob du der globalen (freien) Variable iWert den Wert 5 zuweisen willst, oder der globalen Variable im namespace einBereich.



  • Maiden schrieb:

    Wieso heißt es hier, dass eine mehrdeutigkeit vorliegt?:

    #include <iostream>
    using namespace std;
    
    namespace einBereich {
      // Deklaration im Namensbereich einBereich
      int iwert = 11;
    }
    
    // globale Deklaration
    int iwert = 22;
    
    int main(void) {
    	using namespace einBereich;
    
    	// lokale Deklaration
    	// int iwert = 33;
    
    	iwert = 5;    // Mehrdeutigkeit
    
    	return EXIT_SUCCESS;
    }
    

    Ich hatte mal ein ähnliches Problem, weil ich von einer using-Direktive (using namespace soundso) ein anderes Verhalten erwartet hatte. In den meisten schlauen Büchern steht das einfach nicht gut erklärt drin.

    Die Namenssuche geht "von innen nach außen" und stoppt sofort, wenn eine oder mehrere Deklarationen im aktuellen zu durchsuchenden Gültigkeitsbereich gefunden wurden. Im Falle eines Funktionsaufrufs kommt ggf. noch ADL hinzu (argument-dependent lookup). Eine using-Direktive (using namespace soundso) beeinflusst aber nur die Namenssuche, wenn sie im globalen Gültigkeitsbereich angelangt ist. In diesem Beispiel passiert folgendes:

    • Im Scope von main gibt's kein iwert --> also eine Ebene höher weiter suchen
    • Eine Ebene höher ist hier schon der globale Scope. Und hier werden auch gleichzeitig alle Namensräume der using-Direktiven betrachtet. Der Compiler findet auf dieser Ebene also ::iwert und ::einBereich::iwert
    • Da es sich hier um keinen Funktionsaufruf handelt, findet auch kein ADL statt.
    • Wegen der zwei gefundenen Namen bekommst du den Fehler bzgl Mehrdeutigkeit

    Anders verhält es sich da mit einer using-Deklaration:

    namespace einBereich {
      // Deklaration im Namensbereich einBereich
      int iwert = 11;
    }
    
    // globale Deklaration
    int iwert = 22;
    
    int main(void) {
      // "deklariert" ein iwert in _diesem_ Scope
      using einBereich::iwert; 
    
      iwert = 5; // verändert einBereich::iwert
    
      return EXIT_SUCCESS;
    }
    

Anmelden zum Antworten