3

This is a follow up to this question. Consider the following example:

#include <iostream>

namespace MyProject {
    class string {
        public: string() { std::cout << "Callin string constructor" << std::endl; }
    };
}

namespace Other {
    class string {};
}

namespace MyProject {
    using Other::string;
}

namespace MyProject {
    void useString() {
        const string s;
    }
}

int main() {
    MyProject::useString();
}

Here the compiler correctly throws an error at the line using Other::string, complaining that a declaration for string already exists in that namespace, coming from the previous class string definition.

Now consider this:

#include <iostream>

namespace MyProject {
    class string {
        public: string() { std::cout << "Callin string constructor" << std::endl; }
    };
}

namespace Other {
    class something {};
    using string = something;
}

namespace MyProject {
    using Other::string;
}

namespace MyProject {
    void useString() {
        const string s;
    }
}

int main() {
    MyProject::useString();
}

Here there's no compilation error: I successfully managed to shadow my previous declaration of string with a new one.

  • Why there's no error in the second case? Is it because using string = something is not an actual declaration, since it's an alias and the real declaration is for the something name, and the compiler can only spot conflicts between actual declarations, so in this case it would think that I'm really declaring something and string, and be ok with that?

  • Isn't this quite dangerous? I mean, if these things happen in separate header files without the programmer realizing it, s/he could end up using an identifier that may be something completely different than what s/he thinks, and without the compiler saying anything...

Community
  • 1
  • 1
swahnee
  • 2,661
  • 2
  • 24
  • 34
  • 1
    Which compiler/version? Clang 3.8+ rejects this code as ambiguous (not on the `using` but when declaring `const string s`). – Holt Oct 04 '16 at 07:41
  • @Holt good point, I tested this on g++ 4.9.2. – swahnee Oct 04 '16 at 08:00
  • 2
    vc++ also accepts the code. Looks like all major compilers are wrong, see 7.3.3/13 "Since a using-declaration is a declaration, the restrictions on declarations of the same name in the same declarative region (3.3) also apply to using-declarations." – n. m. could be an AI Oct 04 '16 at 08:12

0 Answers0