これはこの質問のフォローアップです。次の例を検討してください。
#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
。
2 番目のケースでエラーが発生しないのはなぜですか? それ
using string = something
はエイリアスであり、実際の宣言は名前のためのものsomething
であり、コンパイラは実際の宣言間の競合のみを見つけることができるため、実際の宣言ではないためでしょうか。この場合、実際に and を宣言していると見なさsomething
れstring
ます。それでいいですか?これってかなり危険じゃないですか?つまり、プログラマーが気付かないうちにこれらのことが別々のヘッダーファイルで発生した場合、コンパイラーが何も言わずに、彼/彼が考えているものとはまったく異なる識別子を使用することになる可能性があります...