2013-06-25 13 views
11

私は次のコードを記述する場合、それがコンパイルされ、正常に実行されます:グローバルスコープとローカルスコープでディレクティブの動作が異なるのはなぜですか?

#include <iostream> 
using namespace std; 

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

namespace second 
{ 
    double x = 3.1416; 
    double y = 2.7183; 
} 

int main() { 
    using namespace first; //using derective 
    using second::y; 
    cout << x << endl; 
    cout << y << endl; 
    return 0; 
} 

しかし、私は次のように、

using namespace first; //using derective 
using second::y; 
int main() { 
    cout << x << endl; 
    cout << y << endl; 
    return 0; 
} 

をメイン関数外のディレクティブを使用して書く場合には、このコンパイルエラーを与える:

g++  namespace03.cpp -o namespace03 
namespace03.cpp: In function ‘int main()’: 
namespace03.cpp:20:11: error: reference to ‘y’ is ambiguous 
namespace03.cpp:13:10: error: candidates are: double second::y 
namespace03.cpp:7:7: error:     int first::y 
make: *** [namespace03] Error 1 

mainとの内側でディレクティブを使用すると違った動作をする理由を誰でも説明できます?

答えて

10

using宣言はそれだけで宣言です。 mainの内部にあるusing second::y;は、そのスコープ内の変数yを宣言するのと同様に、グローバル名前空間のスコープ内に他のyを隠します。グローバルスコープ内でusing second::y;を使用すると、yの両方が同じスコープにあるため、名前を隠していません。

(説明のために以下のコメントを参照してください)あなたの最初の例は、以下のようなものです想像:

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

int main() { 
    using namespace first; // This makes first::y visible hereafter 
    int y = 20; // This hides first::y (similar to using second::y) 
    cout << x << endl; 
    cout << y << endl; // Prints 20 
} 

は、しかし、第二の例のようなある:

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 
using namespace first; // This makes first::y visible in global scope 
int y = 20; // This is global ::y 
int main() { 
    cout << x << endl; 
    cout << y << endl; // Error! Do you mean ::y or first::y? 
} 
+0

速い返信のためにJesseに感謝します...私が間違っていれば私を修正してください...しかし、ディレクティブを使用しているときにはまだ主要な機能に2つの宣言があります。もしそうなら、なぜコンパイラは2番目のケースでのみ問題を起こすのですか? – Amrit

+1

@ user2235938: 'y'の宣言は2つありますが、using宣言はmainの中で' second :: y'を宣言し、 'first :: y'はグローバル名前空間のスコープで宣言します。 'second :: y'はmainの中で宣言されているので、' first :: y'を隠します。あなたは名前の隠れに慣れていますか? –

+0

申し訳ありませんJesse ...しかし、私は理解できません。両方のステートメントが "名前空間を最初に使用する; 第2の:: y;を使用する主な関数の中にある場合は、ローカルスコープ内の最初の:: yと2番目の:: yの両方を宣言し、コンパイルエラーを返さなければなりません。しかし、プログラムはコンパイルされず、正常に実行されません。そして、両方のステートメントがメインの外側にあるときには、あいまいさのためにコンパイルされません。親切に説明してください... – Amrit

6

2つの大きな違いがありますusing-declarationとusing-directiveの間にあります。

最初の違い:(明らかな違い)。

namespace first{ 

int x=1; 
int y=2; 
} 
using first::x; //using declaration 

これは、明示的な修飾子として変数x名前空間名なしを使用しており、これはyが含まれていないことに注意することができるようになります。

namespace first{ 
int x=1; 
int y=2; 
} 
using namespace first;// using directive 

これは、明示的な修飾子として名前空間名せずに、名前空間first内のすべての変数を使用できるようになります。


秒差:(あなたが理解していなかったものをされています)。

メイン関数内でusingディレクティブとusing宣言の両方を使用すると、エラーは発生しませんが、両方をグローバル名前空間で使用しようとすると、コンパイル時エラーが発生することを説明します。その理由は、using second::y使用して、ディレクティブということです

int main() {  
using namespace first; 
using second::y; 
    cout << x << endl; // this will output first::x; 
    cout << y << endl; // this will output second::y; 
    return 0; 
} 

:例1

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

namespace second 
{ 
    double x = 3.1416; 
    double y = 2.7183; 
} 



は、私たちがこのようなグローバル名前空間で定義された2つの名前空間を持っているとしましょう変数yはスコープのローカル変数のように見えますが、using-directiveはuですsed、この場合はmain関数の内部で使用されます。使用宣言using namespace firstは、この名前空間内で定義された変数をグローバル変数のように見せていますが、これはusingディレクティブが使用されたスコープ内でのみ有効です。この場合、main関数の内部にあります。

例2:

using namespace first; 
using second::y; 

int main() {  
    cout << x << endl; 
    cout << y << endl; // two definitions of y. first::y and second::y 
    return 0; 
} 

あなたは両方first::yいるので、エラーになりますあなたはwhat'veを適用した場合

ので、あなたがこのような何かをした場合のことを知っているだろう、上記述べましたsecond::yは、グローバル名前空間で定義されているかのように動作しますので、最終的にOne Defintion Ruleを破棄します。

関連する問題