読者です 読者をやめる 読者になる 読者になる

using宣言

using指令で名前空間を可視化することができたが、複数の名前空間を可視化すると、結局は他の名前空間のものと重複してしまう本末転倒なことが起きる・・・。
using指令では、ブロック内でその名前空間を持つすべての変数、関数、クラスから名前空間を省略できるので、それがいくつもあると、そういうことも起きてしまう場合が出てくる・・・。

using_declaration.hが、

こういった場合で、using_declaration.cppを、

// ヘッダのインクルード
// 既定のヘッダ
#include <iostream> // C++標準入出力
// 独自のヘッダ
#include "using_declaration.h" // 名前空間test1, test2, test3

// main関数の定義
int main(void){

  // test1, test2ブロック
  {

    // test1, test2を可視化
    using namespace test1;
    using namespace test2;

    // 値の代入
    x = 1;
    y = 2;
    z = 3;

    // 値の出力
    std::cout << x << "," << y << "," << z << std::endl;

  }

  // test2, test3ブロック
  {

    // test2, test3を可視化
    using namespace test2;
    using namespace test3;

    // 値の代入
    x = 4;
    y = 5;
    z = 6;

    // 値の出力
    std::cout << x << "," << y << "," << z << std::endl;

  }

  // test1, test3ブロック
  {

    // test1, test3を可視化
    using namespace test1;
    using namespace test3;

    // 値の代入
    x = 7;
    y = 8;
    z = 9;

    // 値の出力
    std::cout << x << "," << y << "," << z << std::endl;

  }

  // プログラムの終了
  return 0;

}

とする・・・。
しかし、test1, test2ではyが重複、test2, test3ではzが重複、test1, test3ではxが重複してしまい、

$ g++ using_declaration.cpp -o using_declaration
using_declaration.cpp: 関数 ‘int main()’ 内:
using_declaration.cpp:19:5: エラー: reference to ‘y’ is ambiguous
     y = 2;
     ^
In file included from using_declaration.cpp:5:0:
using_declaration.h:8:7: 備考: 候補: int test2::y
   int y; // int型y.
       ^
using_declaration.h:4:7: 備考:       int test1::y
   int y; // int型y.
       ^
using_declaration.cpp:23:30: エラー: reference to ‘y’ is ambiguous
     std::cout << x << "," << y << "," << z << std::endl;
                              ^
In file included from using_declaration.cpp:5:0:
using_declaration.h:8:7: 備考: 候補: int test2::y
   int y; // int型y.
       ^
using_declaration.h:4:7: 備考:       int test1::y
   int y; // int型y.
       ^
using_declaration.cpp:37:5: エラー: reference to ‘z’ is ambiguous
     z = 6;
     ^
In file included from using_declaration.cpp:5:0:
using_declaration.h:14:7: 備考: 候補: int test3::z
   int z; // int型z.
       ^
using_declaration.h:9:7: 備考:       int test2::z
   int z; // int型z.
       ^
using_declaration.cpp:40:42: エラー: reference to ‘z’ is ambiguous
     std::cout << x << "," << y << "," << z << std::endl;
                                          ^
In file included from using_declaration.cpp:5:0:
using_declaration.h:14:7: 備考: 候補: int test3::z
   int z; // int型z.
       ^
using_declaration.h:9:7: 備考:       int test2::z
   int z; // int型z.
       ^
using_declaration.cpp:52:5: エラー: reference to ‘x’ is ambiguous
     x = 7;
     ^
In file included from using_declaration.cpp:5:0:
using_declaration.h:13:7: 備考: 候補: int test3::x
   int x; // int型x.
       ^
using_declaration.h:3:7: 備考:       int test1::x
   int x; // int型x.
       ^
using_declaration.cpp:57:18: エラー: reference to ‘x’ is ambiguous
     std::cout << x << "," << y << "," << z << std::endl;
                  ^
In file included from using_declaration.cpp:5:0:
using_declaration.h:13:7: 備考: 候補: int test3::x
   int x; // int型x.
       ^
using_declaration.h:3:7: 備考:       int test1::x
   int x; // int型x.
       ^
$

こうなる・・・。
そこで、どちらの名前空間の変数かを名前空間を付けて識別させると、

// ヘッダのインクルード
// 既定のヘッダ
#include <iostream> // C++標準入出力
// 独自のヘッダ
#include "using_declaration.h" // 名前空間test1, test2, test3

// main関数の定義
int main(void){

  // test1, test2ブロック
  {

    // test1, test2を可視化
    using namespace test1;
    using namespace test2;

    // 値の代入
    x = 1;
    test1::y = 2;
    z = 3;

    // 値の出力
    std::cout << x << "," << test1::y << "," << z << std::endl;

  }

  // test2, test3ブロック
  {

    // test2, test3を可視化
    using namespace test2;
    using namespace test3;

    // 値の代入
    x = 4;
    y = 5;
    test2::z = 6;

    // 値の出力
    std::cout << x << "," << y << "," << test2::z << std::endl;

  }

  // test1, test3ブロック
  {

    // test1, test3を可視化
    using namespace test1;
    using namespace test3;

    // 値の代入
    test3::x = 7;
    y = 8;
    z = 9;

    // 値の出力
    std::cout << test3::x << "," << y << "," << z << std::endl;

  }

  // プログラムの終了
  return 0;

}

こうなり、

$ g++ using_declaration.cpp -o using_declaration
$ ./using_declaration
1,2,3
4,5,6
7,8,9
$

コンパイルできて、実行もできる・・・。
これでもいいが、using宣言でどの変数がどの名前空間かのものかを宣言させれば、変数に名前空間を付ける必要はなくなり、ちょっとすっきりする・・・。

usingの部分は変数の数の分だけ増えているが、それ以降は名前空間を付けていないのですっきりしている・・・。

$ vi using_declaration.cpp
$ g++ using_declaration.cpp -o using_declaration
$ ./using_declaration
1,2,3
4,5,6
7,8,9
$

これでもコンパイルが通って実行できた・・・。

Sample/cpp/using_declaration/using_declaration/src/using_declaration at master · bg1bgst333/Sample · GitHub