[C++] 名前のない名前空間を使用する理由とその利点は何ですか?


Answers

匿名の名前空間に何かがあるということは、この翻訳単位 (.cppファイルとそのすべてのインクルード)にローカルであることを意味します。つまり、同じ名前の別のシンボルが別の場所で定義されている場合、 One Definition Rule (ODR)に違反しません。

これは、静的なグローバル変数または静的関数を持つCの方法と同じですが、クラス定義にも使用できます(C ++でstaticではなく使用する必要があります)。

同じファイル内のすべての匿名名前空間は同じ名前空間として扱われ、異なるファイル内のすべての匿名名前空間は区別されます。 匿名の名前空間は、次のものと同じです。

namespace __unique_compiler_generated_identifer0x42 {
    ...
}
using namespace __unique_compiler_generated_identifer0x42;
Question

私はちょうど新しいC ++ソフトウェアプロジェクトに参加しました。私はそのデザインを理解しようとしています。 このプロジェクトは名前のない名前空間を頻繁に使用します。 たとえば、次のようなものがクラス定義ファイルで発生する可能性があります。

// newusertype.cc
namespace {
  const int SIZE_OF_ARRAY_X;
  const int SIZE_OF_ARRAY_Y;
  bool getState(userType*,otherUserType*);
}

newusertype::newusertype(...) {...

名前のない名前空間を使用する可能性のある設計上の考慮事項は何ですか? 利点と欠点は何ですか?




この質問に対する他の回答に加えて、匿名の名前空間を使用すると、パフォーマンスが向上する可能性があります。 名前空間内のシンボルは外部リンケージを必要としないため、コンパイラは名前空間内のコードを積極的に最適化することができます。 例えば、ループ内で複数回呼び出される関数は、コードサイズに影響を与えずにインライン化することができます。

たとえば、私のシステムでは、匿名の名前空間が使用されている場合(x86-64 gcc-4.6.3と-O2; add_valの余分なコードは、コンパイラがインクルードしたくないことに注意してください)それは2回)。

#include <iostream>

namespace {
  double a;
  void b(double x)
  {
    a -= x;
  }
  void add_val(double x)
  {
    a += x;
    if(x==0.01) b(0);
    if(x==0.02) b(0.6);
    if(x==0.03) b(-0.1);
    if(x==0.04) b(0.4);
  }
}

int main()
{
  a = 0;
  for(int i=0; i<1000000000; ++i)
    {
      add_val(i*1e-10);
    }
  std::cout << a << '\n';
  return 0;
}



無名の名前空間は、クラス、変数、関数、およびオブジェクトの定義されたファイルへのアクセスを制限します。 名前空間の無しの機能は、C / C ++のstaticキーワードに似ていstatic
staticキーワードは、グローバル変数と関数が定義されているファイルへのアクセスを制限します。
名前のない名前空間とstaticキーワードの間には違いがあります。名前のない名前空間は静的なものよりも利点があります。 staticキーワードは、変数、関数、オブジェクトで使用できますが、ユーザー定義のクラスでは使用できません。
例えば:

static int x;  // Correct 

しかし、

static class xyz {/*Body of class*/} //Wrong
static structure {/*Body of structure*/} //Wrong

しかし、名前のない名前空間でも同じことが可能です。 例えば、

 namespace {
           class xyz {/*Body of class*/}
           static structure {/*Body of structure*/}
  } //Correct