Exact Duplicate: 明示的な名前空間と C++ での「使用」のどちらを好みますか?
名前空間を使用するための推奨規則は次のうちどれですか?
using namespace std;
また
using std::cin;
using std::cout;
また
コードで必要に応じて関数を呼び出しますか?
std::cout<<"Hello World!"<<std::endl;
Exact Duplicate: 明示的な名前空間と C++ での「使用」のどちらを好みますか?
名前空間を使用するための推奨規則は次のうちどれですか?
using namespace std;
また
using std::cin;
using std::cout;
また
コードで必要に応じて関数を呼び出しますか?
std::cout<<"Hello World!"<<std::endl;
非常に良い説明がここにあります。
最初のスタイル、つまり名前空間を使用すると、名前空間の目的全体が無効になります。小さなコード スニペット以外では使用しないでください。(私もそこでは使用しません!:D)
2番目のものは冗長すぎます。実用的ではありません。
個人的には、完全修飾名 (std::cout など) を入力する 3 番目のスタイルが好きです。
コードは書かれるよりもはるかに多く読まれることを忘れないでください。完全修飾名 IMO を使用すると、コードが読みやすくなります。
これは以前に何度も尋ねられましたが、私の SO 検索 fu はしばらく私を見捨てたようです。基本的:
ヘッダー ファイルには、いかなる種類の using ディレクティブも含めないでください。これを行うと、コードが汚染され、あらゆる種類の追跡が困難なバグが発生します。
using std::string
そのような型を多用する実装 (.cpp) ファイルでは、 のような using 宣言を優先します。
最後の手段として、を使用using namespace std
しますが、実装ファイルでのみ使用します。便宜上、SO のコンパイル可能なコードの投稿で使用します。
これは、同じ件名で私が書いた別の回答の修正版です。これらの質問は十分にあり、おそらく私は決定的な投稿に終わるでしょう;)
主な問題は名前の競合です。コード内に cout という変数がある場合、using namespace std;
意味が曖昧になります。それだけではありませんcout
。count
、reverse
またequal
含まれますが、これらはすべて共通の識別子です。
コンパイラの問題はすべて無視して、あなたのコードを読みに来る人にとっても問題です。これらの余分な 5 文字により、コードを保守する次の人が、あなたの意図を正確に理解できるようになります。
また、決して入れてはならないことにも注意してください。
using namespace std;
ヘッダー ファイルでは、その名前空間を使用したくない場合でも、そのヘッダー ファイルを含むすべてのファイルに伝播できるためです。ここでのもう 1 つの問題は、std 名前空間がインポートされたことも明確ではないことです。そのため、メンテナー (または 3 か月後のあなた) は、同じコンパイル ユニットに含まれていたいくつかのあいまいな std 関数と同じ名前の変数を追加し、次に、コンパイル エラーの原因を探すのに 1 時間かかります。
ほとんどの場合、次のようなものを使用することは非常に有益です
using std::swap
特殊なバージョンの swap があるかのように、コンパイラはそれを使用しますが、そうでない場合は にフォールバックしstd::swap
ます。を呼び出す場合はstd::swap
、常に基本バージョンを使用します。これは、特殊化されたバージョンを (存在する場合でも) 呼び出しません。
pimpl イディオムを使用したコードを例にとります。デフォルトのコピーは実際の実装のすべてのデータをコピーする可能性がありますが、必要なのはポインタを交換することだけです。特殊化されたスワップを使用すると、実行時間を大幅に節約できます。適切に設計されたライブラリは、それを特殊化する必要があります。
要約すれば、
常にusing std::swap
優先std::swap()
using namespace std
伝播のためにヘッダーでは絶対に避けてください。実装ファイルでは使用しないようにしてください。
using std::foo
すべてのファイルの先頭に数千を配置することは、適切な方法ではありません。ほとんどの場合、一般的に使用されるクラスに使用します。
それ以外は意見です。
私は個人的に3番目のオプションを好みます。これを見てください:
namespace A { int a=0; }
namespace B { int a=0; }
そしてあなたはそれを次のように使用します:
using namespace A;
using namespace B;
using namespace std;
cout<<a<<endl; //error here!
代わりに、あなたがただ言うことができれば、
std::cout<<B::a<<std::endl; //No problem, more readable
コードを入力するのに少し時間がかかるかもしれませんが、2番目と3番目のオプションの方が(一種の)好ましいです。
これはスタイルの問題ですが、1 つだけ: 名前空間をグローバル スコープにインポートしないでください。例えば:
#include <iostream>
using namespace std; // Pollution!
int main()
{
....
}
名前空間をインポートする場合は、作業中のスコープにインポートするだけです。
#include <iostream>
int main()
{
using namespace std; // Good!
....
}
using namespace foo
範囲が限定されていることを指摘したいと思います。例:
#include <iostream>
#include <vector>
//...
for (int i=0; i<10; ++i)
{
using namespace std;
cout << i << endl;
}
vector v; // won't compile
注意して使用すると、using namespace std
有用であると同時に無害になります。
私は常に完全な名前空間をリストします。読みやすさが向上し、関数やデータがどこから来ているかを他の人に知らせることができます。 using
他の人のコードを読むとき、特に私が何かを学ぼうとしているときに、それがその名前空間の一部なのか他の名前空間の一部なのか分からないため、非常に面倒です。そして、これらの他の賢明な人々が言っているように、それは名前空間の要点全体を無効にしますよね? ポイントは、すべてを分離し、データとロジックに意味を持たせることです。
覚えておくべき良い順序: 最も重要な人物は、プログラムを使用するクライアントです。2 番目に重要なのは、あなたのコードを維持している、またはあなたのコードから学ぼうとしている他のコーダーです。最も重要でないのはあなたです。:-)
名前空間が std の場合、完全修飾名を書き出すことをお勧めします。ここで、std:: は 5 文字しか追加しません。名前空間がスタックすると、それはまったく別の問題であり、次のような記述に直面します。
if (NumberOfInstances > 0 && (code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_GREEN ||
code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_YELLOW)) {
特に、行を 80 文字に制限する企業スタイルのガイドラインがあり、さらにいくつかのインデントを追加する場合. そのようなものは、すべての言い回しの背後にあるコードのロジックを覆い隠します。その時点で、読みやすさのために、および/またはローカル名前空間エイリアスを使用することに感謝し始めます。
あなたが好むものは何でも。本当に、それは問題ではありません。ただし、ほとんどのコード スニペットは
using namespace std;