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を訴えます。stringclass 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 を宣言していると見なさsomethingstringます。それでいいですか?

  • これってかなり危険じゃないですか?つまり、プログラマーが気付かないうちにこれらのことが別々のヘッダーファイルで発生した場合、コンパイラーが何も言わずに、彼/彼が考えているものとはまったく異なる識別子を使用することになる可能性があります...

4

0 に答える 0