3

这是对这个问题的跟进。考虑以下示例:

#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 = somethingis not an actual declaration,因为它是别名,而真正的声明是针对something名称的,编译器只能发现实际声明之间的冲突,所以在这种情况下,它会认为我真的在声明somethingand string,并且是可以吗?

  • 这不是很危险吗?我的意思是,如果这些事情在程序员没有意识到的情况下发生在单独的头文件中,他/她最终可能会使用一个可能与他/她认为的完全不同的标识符,并且编译器不会说任何东西......

4

0 回答 0