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 thesomething
name, and the compiler can only spot conflicts between actual declarations, so in this case it would think that I'm really declaringsomething
andstring
, 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...