2016-01-08 8 views
10

優雅さ、カプセル化、およびADL(Argument Dependent Lookup)を利用するためには、関数の引数の名前空間の中に関数を定義するのが一般的です。バイナリ演算子に最適な名前空間は何ですか?

異なる名前空間に2つのライブラリがあるとします。 1)1つはライブラリの一部で、もう1つは第三者(例えばブースト)、2)私は両方を制御する、3)私はnone(単に "glue"コードを書く)の3つのケースがあります。

私はこのような何かを持って、私はAへの「ストリーム」Bしたい

namespace ns_A{ 
    struct A{...}; // something that looks like iostream 
} 
namespace ns_B{ 
    struct B{...}; 
} 

は、最良の選択肢

namespace ???{ // what is more correct ns_A, or ns_B? 
    A& operator<<(A& a, B const& b){...} 
} 

または私は両方の名前空間に置くべきでしょうか?

namespace ns_B{ 
    A& operator<<(A& a, B const& b){...} 
} 
namespace ns_A{ 
    using ns_B::operator<<; 
} 

このようなバイナリ関数を定義するのに最適な名前空間はどれですか?

(C++ 11の名前空間をインラインで任意の勧告を変更していますか?)

(他のものが等しい場合、ので、私は例operator<<を使用することがが直感的namespace ns_Bを好む方が良いようです。)

+2

あなたが制御していない名前空間を嫌うことはありません。 – Walter

答えて

4

どちらの名前空間にも演算子を入れることができます。ベストプラクティスとして、コードに属する名前空間に配置することをお勧めします。

5

ケース1の場合、簡単です:あなたがコントロールするnamespaceに入れてください。

ケース2の場合、それはあなたの選択次第です。あなたの例では、私はns_Bを好むでしょう。

厄介な唯一の状況は3です。実際にはnamespaceに追加しないでください。新しい 'グルー'機能を独自の第3のnamespace mineの一部として使用したい場合は、それを自然にそこに入れ、mine内のその機能の使用は自動的に解決されます。当然ながら、これはADLを呼びかけることはありませんが、あなたが望むのはmine内の新しい機能を他の場所で使用することなので、ADLを必要としません。

1

私の提案:名前空間は一切使用しないでください。 ns_Aのコード自体には、ns_Aに何かが存在することは認識されていません。それには依存しません。したがって、ns_Bns_Aのコンストラクトに関するコードはns_Aに属しません。対称性によって、ns_Bについても同様です。

あなたoperator<<おそらく名前空間ではありません(ただし、ns_Aがある場合ns1::ns2ns_Bが、その後ns1を使うns1::ns3ある)ns_Ans_Bの間で「少なくとも共通の名前空間」にする必要があります。

私の意見では、それが明らかに属していない名前空間にコードを強制することは、概念的にはエレガントでなくカプセル化を破ります。 ADLについては、「一般的な名前空間」がns_Ans_Bであること以上のものは期待できません。

+0

大胆な推薦はもちろんです。これは検討するオプションです。最も重要な部分は、ADLに関する良いことが効いていることです。 – alfC

関連する問題