2016-04-27 9 views
5

私は、ソースファイルの "実際の"コードの前に現われる必要がある約1000行のユーティリティクラス定義を含む、古いコードの大した部分を継承しました。また、従来のクラスが関連付けられている可能性のある他のモジュールとの衝突を避けるために、私は無名の名前空間にユーティリティクラスを入れている:コンパイル単位ごとに名前のない名前空間は1つしかありませんか?

namespace { 
    class OldUtils { 
     OldUtils(); 
     int foo(); 
     double bar(); 
    }; 

    OldUtils::OldUtils() { 
     // hundreds of lines 
    } 

    int OldUtils::foo() { 
     // hundreds more lines 
    } 

    ... 
} 

class ActuallyInteresting { 
    // uses OldUtils 
}; 

しかし、私は人々が(実際に)に興味があるだろうActuallyInterestingコードを持っていることを好むだろうファイルの先頭近くに、例えばライン50から始まり、底部で右よりも高い。 horridユーティリティクラスを別のコンパイル単位に分割することはオプションではありません。これは、より高いレベルの理由で私は取り掛かりません!

私は、メソッド定義を持たない短いクラス宣言をファイルの先頭の名前のない名前空間に入れ、もっと長いメソッド定義を別の名前のない名前空間の一番下に置くことが可能かどうか疑問に思っています:

namespace { 
    class OldUtils { 
     OldUtils(); 
     int foo(); 
     double bar(); 
    }; 
} 

class ActuallyInteresting { 
    // uses OldUtils 
}; 

namespace { 
    OldUtils::OldUtils() { 
     // hundreds of lines 
    } 

    int OldUtils::foo() { 
     // hundreds more lines 
    } 

    ... 
} 

は、これら二つの「分離」名前の名前空間は、コンパイル・ユニット内の同じ範囲として扱われ、又は異なる一意の名前空間は、それぞれについて生成されますか?標準はこれについて何か言いたいことはありますか?次のコードはコンパイルする場合

+0

各無名の名前空間は(翻訳単位で静的と同じ)、各翻訳単位に固有になります –

+0

DieterLü[email protected]:これがtrueの場合、1回のアクセス別の翻訳単位で無名の名前空間のグローバル変数をどうしますか?他の翻訳単位の名前がスコープ解決テキストに追加されますか? –

答えて

4

これら二つの「分離」名前の名前空間は、コンパイル単位内で同じ 範囲として扱われ、又は異なる一意の名前空間は、それぞれに対して生成さ のだろうか?規格には といって何も言いませんか?

はい、コンパイル単位内で同じものとして扱われます。そして標準が

latest standard draft引用....言いたいことがあるん...それは

に置き換えられたかのように

$7.3.1.1無名の名前空間を定義の動作(強調は私です) inlineはそれが 無名の名前空間を定義し、の出現をすべて表示されます場合にのみ表示されます

inlineopt namespace unique { /* empty body */ } 
using namespace unique ; 
namespace unique { namespace-body } 

翻訳単位でunique同じ識別子によって置き換えられており、この 識別子は、この短いプログラムをコンパイル翻訳単位

内のすべての他の識別子とは異なり、あなたのコンパイラは、変数の再宣言を訴える必要があります...

namespace { int c = 0; } 
namespace { double c = 8; } 

int main(){ ++c; } 

しかし、名前のない名前空間の変数にアクセスするには、通常の方法でグローバル変数にアクセスします。したがって、これは動作します。

namespace { int c = 0; } 
namespace { void f(){ c = 8; } } 

int main(){ ++c; } 
-2

あなたは、単にチェックすることで答えを自分で把握することができます。各名前空間は一意である場合

namespace { 
    int a; 
} 

namespace { 
    int *b=&a; 
} 

あなたは、コンパイルエラーを得ることを期待します。どちらの場合も、名前のない名前空間が同じ名前空間であれば、問題なくコンパイルできます。

+0

私はこの静脈で基本的なテストを行ったと言わねばならないでしょう(それはうまくいくようです)。しかし、それは標準、またはコンパイラ依存の未定義の動作によって保証されていますか?おかげで – andybuckley

+2

ちょうどコンパイラを使用してコードを標準化していません。 MSVSは、非標準的な 'int&var = some_function_that _retunrs_int()'をうれしくコンパイルします。 – NathanOliver

関連する問題