5

c++11 標準のセクション 7.3.4.2 から:

using-directiveは、指定された名前空間の名前が using-directive の後に using-directive が現れるスコープで使用できることを指定ます。非修飾名のルックアップ (3.4.1) では、名前は、 using ディレクティブと指定された名前空間の両方を含む、最も近い外側の名前空間で宣言されているかのように表示されます。[ 注: このコンテキストで「含む」とは、「直接的または間接的に含む」ことを意味します。—終わりのメモ]

2番目と3番目の文は正確にはどういう意味ですか? 例を挙げてください。

これが私が理解しようとしているコードです:

namespace A
{
    int i = 7;
}
namespace B
{
    using namespace A;
    int i = i + 11;
}
int main(int argc, char * argv[])
{
    std::cout << A::i << " " << B::i << std::endl;
    return 0;
}

私が期待するように、「7 18」ではなく「7 7」と印刷されます。

タイプミスで申し訳ありませんが、プログラムは実際には「7 11」を出力します。

4

2 に答える 2

5

コード内のusingステートメントは無関係です。のイニシャライザが評価されるB::iとき、すでにスコープ内にあります。ステートメントB::iを削除することで、これを自明に証明できます。usingコードはまったく同じようにコンパイルして実行する必要があります。いずれにせよ、 の値はB::i初期化されていない値 (つまり、B::i初期化子が評価されたときに持っていた値) に依存するため、最終的には未定義になります。

于 2012-09-20T22:17:38.917 に答える
3

未定義の動作を排除する:

namespace A
{
    int i = 7;
}
namespace B
{
    using namespace A;
    int tmp = i + 11;
    int i = tmp;
}
#include <iostream>
int main()
{
    std::cout << A::i << " " << B::i << std::endl;
    return 0;
}

標準の意味は、

    int tmp = i + 11;

名前iは、「using ディレクティブと指定された名前空間の両方を含む、最も近い囲み名前空間」に表示されます。using ディレクティブnamespace B、指名された名前空間がnamespace A;であるときに表示されます。最も近い外側の名前空間はグローバル名前空間であるため、 のようiに表示され::iます。これは、名前iがグローバル名前空間に既に存在する場合、コードがあいまいであることを意味します。

より複雑な例:

namespace A {
    namespace B {
        namespace C {
            int i = 4;
        }
    }
    namespace D {
        using namespace B::C;
        namespace E {
            int j = i;
        }
    }
}

の行int j = ii、using ディレクティブ (つまりA::D) と指定された名前空間 ( ) の最も近い囲み名前空間 ( A::B::C) に表示されますA。したがって、A::Dusing ディレクティブの後、および 内A::D::Eでも、非修飾名iは、A::B::C::iとして表示されることA::i、 any をシャドウすること、 any::iと競合すること、および anyまたは( 内で)A::iによってシャドウされることを参照できます。A::D::iA::D::E::iA::D::E

int i = 1;                // shadowed by A::B::C::i appearing as A::i
namespace A {
    int i = 2;            // conflicts with A::B::C::i appearing as A::i
    namespace B {
        int i = 3;        // irrelevant
        namespace C {
            int i = 4;    // nominated; appears as A::i
        }
    }
    namespace D {
        int i = 5;        // shadows A::B::C::i appearing as A::i
        using namespace B::C;
        namespace E {
            int i = 6;    // shadows A::B::C::i appearing as A::i
            int j = i;
        }
    }
}

名前が修飾されていない名前の検索中に表示されるからといって、それが実際 A::i存在するわけではないことに注意してください。修飾名は、引き続き実際の名前(存在する場合) のみを参照します。A::iA::i

于 2012-09-21T13:37:06.727 に答える