这是this question的后续行动。请考虑以下示例:
#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();
}
这里编译器正确地在行using Other::string
处抛出一个错误,抱怨该命名空间中已存在string
的声明,来自之前的class string
定义。
现在考虑一下:
#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();
}
这里没有编译错误:我成功设法用新的string
隐藏了我之前的using string = something
声明。
为什么第二种情况没有错误?是因为something
不是真正的声明,因为它是别名,真正的声明是something
名称,编译器只能发现冲突在实际声明之间,所以在这种情况下它会认为我真的声明string
和cron
,并且对此好吗?
这不是很危险吗?我的意思是,如果这些事情发生在单独的头文件中而没有程序员意识到这一点,那么他/她最终可能会使用一个标识符,这可能与他/她的想法完全不同,并且没有编译器说什么......