std名前空間の使用


110

std名前空間に関して 'using'を使用することについては、さまざまな見方があるようです。

using namespace std」を使用すると言う人もいれば、「」で使用するstd関数にプレフィックスを付けるのではなく、プレフィックスを付けるstd::人もいます。

using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::vector;

使用されるすべてのstd関数用。

それぞれの長所と短所は何ですか?




回答:


131

ほとんどのC ++ユーザーは、、などを読んstd::stringで非常に満足していますstd::vector。実際、raw vectorを見ると、これがstd::vectorユーザー定義か別のユーザー定義かどうかがわかりませんvector

私は常に使用に反対していusing namespace std;ます。これは、あらゆる種類の名前をグローバル名前空間にインポートし、あらゆる種類の明白でないあいまいさを引き起こす可能性があります。

std名前空間にあるいくつかの一般的な識別子は次のとおりです:カウント、並べ替え、検索、等しい、逆。ローカル変数が呼び出されるcountということusing namespace stdは、countではなくを使用できないことを意味しますstd::count

不要な名前の競合の典型的な例は次のようなものです。あなたが初心者で、について知らないと想像してくださいstd::count。あなたが何か他のものを使っているか、それが<algorithm>一見無関係なヘッダーに引っ張られていると想像してください。

#include <algorithm>
using namespace std;

int count = 0;

int increment()
{
    return ++count; // error, identifier count is ambiguous
}

std::countいくつかの長いネストされた型を含むテンプレートであるため、通常、エラーは長く、扱いにくいものです。

ただし、これは問題ありません。std::countグローバルネームスペースに入り、関数の数によって非表示になるためです。

#include <algorithm>
using namespace std;

int increment()
{
    static int count = 0;
    return ++count;
}

おそらく少し意外なことに、これで問題ありません。宣言的スコープにインポートされた識別子は、それらが定義されている場所とインポートされる場所の両方を囲む共通の名前空間に表示されます。つまり、std::countcountグローバルネームスペースと同じように表示されますが、の内部のみincrementです。

#include <algorithm>

int increment()
{
    using namespace std;
    static int count = 0;
    return ++count;
}

そして同様の理由で、countここではあいまいです。using namespace stdは発生しません。予想されるstd::countように外側countを非表示にします。using namespace規則手段std::count(中ルックスincrement関数は)それはつまり、同じ範囲で、グローバルスコープで宣言されたかのようにint count = 0;、したがって、あいまいさの原因となります。

#include <algorithm>

int count = 0;

int increment()
{
    using namespace std;
    return ++count; // error ambiguous
}

21
しかし種類サイコーのstd ::接頭辞なしの方がはるかに簡単!
xtofl 2009

69
@xtofl:いいえ、ありません。5文字は入力時にそれほど関係ありませんが、これらの5文字は読むときに非常に関係があるかもしれません。また、コードは記述よりもはるかに読みやすいため、読みやすさはソースコードの入力のしやすさよりもはるかに重要です。
sbi 2009

3
usingステートメントがスコープルールで正しく動作することを追加できます。
マーティンヨーク

2
@Martin York:スコーピングルールを示す例で更新されました。@Michael Burr:それは間違いなくそれほど悪くない、私が本当に嫌いなのは、単純な間違いのエラーメッセージが解釈するのが非常に難しくなるところ、またはそれらがまったく起こらないところです。たとえば、関数がスコープ内にあると考えられているが、そうではなく、std ::関数がそうである場合、有用な「識別子が認識されない」エラーが発生するのではなく、よりわかりにくい「引数を変換できない」という結果になることがよくあります。 X 'または'テンプレートから関数を生成できません 'スタイルエラー。さらに悪いのは、間違った関数が黙って呼び出された場合です。まれですが、起こります。
CBベイリー

5
さて、のオプションについて誰も議論しなかったことに驚いていますusing std::xxx;。名前空間を汚染することはありません。コードの記述はより短くなり、私copyよりもずっと読みやすいと思いますstd::copy
legends2k 2010

41

基本を除く(すべてのstlオブジェクト/関数の前にstd ::を追加する必要があり、 'using namespace std'がない場合は競合の可能性が低くなります)

あなたが決して置くべきではないことも注目に値します

using namespace std

ヘッダーファイルでは、その名前空間を使用したくない場合でも、そのヘッダーファイルを含むすべてのファイルに伝播する可能性があります。

場合によっては、次のようなものを使用すると非常に有益です

using std::swap

swapの特別なバージョンがあるかのように、コンパイラはそれを使用しstd::swapます。それ以外の場合は、にフォールバックします。

を呼び出す場合はstd::swap、常に最適化されたバージョン(存在する場合)を呼び出さない基本バージョンを使用します。


10
言及するための+1 using std::swap(これは私がこれまでに使用した唯一のものです)。
sbi 2009

1
u n s伝播する可能性があることを言及した場合は+1 。正しく構築されたヘッダーに侵入する可能性があることにも注意してください。不正なヘッダーの後に含める必要があります。
quamrana 09/09/05

1
しかし、swapor move(またはhashlessなど)の特殊化を定義している場合は、namespace stdとにかくその特殊化を行う必要があります。例:namespace std {template<> class hash<X> {public: size_t operator()(const X&) const};} class X: {friend size_t std::hash<X>::operator()(const X&)};
AJMansfield 2015年

28

まず、いくつかの用語:

  • using-declarationusing std::vector;
  • using-directiveusing namespace std;

ヘッダーファイルのグローバルスコープで使用されていない限り、usingディレクティブの使用は問題ないと思います。だから

using namespace std;

.cppファイル内の問題は実際には問題ではありません。問題が発生した場合は、完全に管理下にあります(必要に応じて、特定のブロックにスコープを設定することもできます)。多数のstd::修飾子を使用してコードを乱雑にする特別な理由はありません。それは単なる視覚的なノイズになります。ただし、stdコードで名前空間からの名前の集まり全体を使用していない場合は、ディレクティブを省略しても問題はありません。これはトートロジーです-ディレクティブが必要なければ、それを使用する必要はありません。

同様に、名前空間の特定の型に対して(using-directivesの代わりに)いくつかのusing宣言で問題が解決しない場合は、特定の名前だけを現在の名前空間に持ち込むべきではない理由はありません。同じように、1つのusingディレクティブでもうまくいく場合は、25か30のusing宣言を行うのはおかしく、簿記は面倒だと思います。std

また、using宣言を使用する必要がある場合があることも覚えておくとよいでしょう。スコットマイヤーズの「Effective C ++、Third Edition」の「Item 25:Non-throwing swap for support for a non-throw swap」を参照してください。テンプレート化された汎用的な関数でパラメーター化された型に「最良の」スワップメソッドを使用するには、使用宣言と引数に依存するルックアップ(ADLまたはKoenigルックアップとも呼ばれます)を利用する必要があります。

template< typename T >
void foo( T& x, T& y)
{
    using std::swap;     // makes std::swap available in this function

    // do stuff...

    swap( x, y);         // will use a T-specific swap() if it exists,
                         //  otherwise will use std::swap<T>()

    // ...
 }

名前空間を大幅に使用するさまざまな言語の一般的なイディオムを検討する必要があると思います。たとえば、JavaとC#はネームスペースをかなりの範囲で使用しています(おそらくC ++よりも多く)。これらの言語で名前空間内の名前を使用する最も一般的な方法は、usingディレクティブと同等の機能を使用して、それらをまとめて現在のスコープに入れることです。これは広範囲にわたる問題を引き起こさず、問題であることがまれに、完全修飾名を介して問題の名前を処理することによって、またはC ++で行うことができるのと同じようにエイリアスを使用して、「例外」ベースで処理されます。

Herb SutterとAndrei Alexandrescuは、彼らの本、C ++ Coding Standards:101 Rules、Guidelines、and Best Practicesの「Item 59:Do n't write namespace usings in a header file or before the #include before」をこのように述べています。

つまり、宣言の後の実装ファイルで宣言とディレクティブを自由に使用して名前空間を使用できます#include。反対の主張が繰り返されているにもかかわらず、宣言とディレクティブを使用した名前空間は悪ではなく、名前空間の目的を損なうことはありません。むしろ、それらは名前空間を使用可能にするものです。

Stroupstrupは、「C ++プログラミング言語、第3版」で、「グローバル名前空間を汚染しないでください」とよく言われます。彼は実際にそれを言う(C.14 [15])が、C.10.1の章を参照して彼はこう言っている:

using宣言はローカルスコープに名前を追加します。使用して、ディレクティブはありません。宣言されたスコープでアクセス可能な名前をレンダリングするだけです。例えば:

namespaceX {
    int i , j , k ;
}

int k ;
void f1()
{
    int i = 0 ;

    using namespaceX ; // make names from X accessible

    i++; // local i
    j++; // X::j
    k++; // error: X::k or global k ?

    ::k ++; // the global k

    X::k ++; // X’s k
}

void f2()
{
    int i = 0 ;

    using X::i ; // error: i declared twice in f2()
    using X::j ;
    using X::k ; // hides global k

    i++;
    j++; // X::j
    k++; // X::k
}

ローカルで宣言された名前(通常の宣言またはusing宣言のいずれかで宣言)は、同じ名前の非ローカル宣言を非表示にし、名前の不正なオーバーロードは宣言の時点で検出されます。

以下のための曖昧エラーに注意してくださいk++では f1()。グローバル名は、グローバルスコープでアクセス可能にされた名前空間の名前よりも優先されません。これは、偶発的な名前の衝突に対する重要な保護を提供し、さらに重要なことには、グローバル名前空間を汚染することから得られる利点がないことを保証します。

多くの名前を宣言するライブラリがusingディレクティブを介してアクセス可能になる場合、未使用の名前の衝突がエラーと見なされないことは大きな利点です。

...

名前空間を使用する新しいプログラムでは、従来のCおよびC ++プログラムと比較して、グローバル名の使用が大幅に減少することを期待しています。名前空間の規則は、グローバルスコープを汚染しないように注意する誰かよりもグローバル名の「怠惰な」ユーザーに利点を与えないように特別に作成されました。

そして、どのように「グローバル名の怠惰なユーザー」と同じ利点を持っていますか?名前空間の名前を現在のスコープで安全に使用できるようにするusingディレクティブを利用する。

違いがあることに注意してくださいstd。usingディレクティブを適切に使用してスコープで使用できるようにされた名前空間の名前(ディレクティブをの後ろに配置することにより#includes)は、グローバル名前空間を汚染しませ。それらの名前を簡単に利用できるようにするだけであり、衝突に対する継続的な保護を備えています。


あなたの最後のポイントに関して:JavaとC#にも多くのすっきりした名前空間があります。BCLのすべてがシステムに存在する場合、「システムを使用」は「名前空間stdを使用」と同じくらいの問題を引き起こします。
ジェフハーディ

しかし、私が目にするJavaおよびC#プログラムは、通常、「システム」(またはそれに相当するもの)だけでなく、使用するすべての名前空間を持ち込みます。したがって、使用されるすべての名前を取り込む単一のusingディレクティブの代わりに、多かれ少なかれ同じことを行う5または10があります。また、「名前空間stdの使用」も行います。本当にそんなに厄介なの?
マイケルバー

問題は、stdの共通名が多すぎることと、1つの標準ヘッダーを含めると他のすべてが含まれる場合があることです。何を輸入するかを適切に管理することはできません。リスクが多すぎます。JavaとC#についてはよく知りませんが、C ++よりもはるかに優れたモジュールシステムであり、通常、名前のインポートが嫌われるAdaについては知っています。一般に、その最初の命名規則の問題(名前空間だけでなく、接頭辞を使用する人々を見てきたが、インポートでは意味がない)はスタイルの問題である。
AProgrammer 2009

1
これが現実の問題であると私はまだ確信していません。私は、usingディレクティブが常に重大な欠点なしに使用されているのを目にしています。繰り返しになりますが、使用しなくても問題ありません。私はstd::修飾子がコードを散らかさないことを好むだけです-それを回避する他の方法があります(通常、using宣言またはtypedefでうまくいきます)。
マイケルバー

1
@AProgrammer:あなたは「リストはlispインタープリターでリストを識別するための自然な識別子です」と言いますが、「using namespace std;」ディレクティブを使用しても自然識別子 ' list'を宣言できなくなるわけではありません。それstd::listを修飾せずに長く使用します。これは、 " using namespace std;"ディレクティブがない場合と同じです。それとも何か不足していますか?
マイケルバー

17

ヘッダーファイルのグローバルスコープで名前空間を使用しないでください。これは競合につながる可能性があり、競合が発生したファイルの担当者は原因を制御できません。

実装ファイルでは、選択肢が適切にカットされていません。

  • 使用ネームスペースstdを置くと、そのネームスペースからすべてのシンボルが取得されます。追加されるシンボルを話さずに、ほとんどの人がそこにあるすべてのシンボルを知っている(したがって、衝突がないというポリシーを適用することは不可能です)ので、これは厄介なことです。また、C ++標準では、ヘッダーが他のヘッダーからシンボルを追加できるようになっています(Cでは許可されていません)。制御された場合の記述を単純化するために、実際にはうまく機能します。そしてエラーが発生した場合、問題のあるファイルで検出されます。

  • std :: nameを使用して書き込みます。未知のシンボルをインポートするリスクなしに書くことが簡単であるという利点があります。コストは、必要なすべてのシンボルを明示的にインポートする必要があることです。

  • 明示的に修飾することで多少の混乱が生じますが、一部の練習では問題が少ないと思います。

私のプロジェクトでは、すべての名前に明示的な修飾を使用し、std :: nameを使用して受け入れます。名前空間stdを使用して対抗します(独自のリストタイプを持つlispインタープリターがあるため、競合は確実です)。

他の名前空間については、使用される命名規則も考慮する必要があります。名前付け(バージョン管理用)と名前のプレフィックスを使用するプロジェクトを知っています。using namespace Xthenを行うことにはほとんどリスクがなく、それを行わないとばかげて見えるコードにつながりますPrefixNS::pfxMyFunction(...)

シンボルをインポートしたい場合があります。std :: swapが最も一般的なケースです。std:: swapをインポートしてから、修飾なしのswapを使用します。引数に依存するルックアップは、タイプの名前空間に適切なスワップがある場合はそれを見つけ、ない場合は標準テンプレートにフォールバックします。


編集:

コメントの中で、マイケル・バーは紛争が現実の世界で発生するのかどうか疑問に思っています。これが実際のライブの例です。lisp方言である拡張言語があります。私たちのインタープリターには、lisp.hを含むインクルードファイルがあります。

typedef struct list {} list;

次のようなコード(「engine」と名付けます)を統合して適応させる必要がありました。

#include <list>
...
using std::list;
...
void foo(list const&) {}

したがって、次のように変更しました。

#include <list>

#include "module.h"
...
using std::list;
...
void foo(list const&) {}

良い。すべてが機能します。数か月後、「module.h」が「list.h」を含むように変更されました。テストに合格しました。「モジュール」は、そのABIに影響を与える方法で変更されていなかったため、「エンジン」ライブラリは、ユーザーを再コンパイルせずに使用できました。統合テストは問題ありませんでした。新しい「モジュール」が公開されました。エンジンの次のコンパイルは、コードが変更されていないときに壊れました。


1
名前空間の使用が許容できると私が思う制御されたケースの1つは、コードの公開です。簡素化により、ページのレイアウトが容易になり、露出したポイントに集中するのに役立ちます。欠点は、それが実際に良い方法を示していないため、初心者向けの本では使用しないことです。
AProgrammer 2009

1
std ::と入力すると、わかりやすくするための小さな料金になります
paoloricardo

4
@paoloricardo:一方、私はstd ::があると思います。
マイケルバー

1
@マイケル:あなたはあなたのお金を支払い、あなたはあなたの選択をする!
paoloricardo 2009

2
遭遇した問題の詳細を追加していただきありがとうございます。
マイケルバー

4

コード内でstdおよび他のライブラリと名前が競合するリスクがない場合は、次を使用できます。

using namespace std;

ただし、ドキュメントに対するコードの依存関係を正確に知りたい場合、または名前の競合のリスクがある場合は、別の方法を使用してください。

using std::string;
using std::cout;

3番目のソリューションは、これらのソリューションを使用せずにstd:を記述します。コードを使用するたびにセキュリティが強化されますが、コードに少し重さがあるかもしれません...


4

両方とも

using std::string;

そして

using namespace std;

いくつかのシンボル(1つまたは多数)をグローバル名前空間に追加します。また、グローバル名前空間にシンボルを追加することは、ヘッダーファイルでは絶対に行うべきではありません。誰がヘッダーをインクルードするかを制御することはできません。他のヘッダーを含むヘッダー(およびヘッダーを含むヘッダーを含むヘッダーなど)はたくさんあります。

実装(.cpp)ファイルでは、それはあなた次第です(すべての#includeディレクティブのに実行することを忘れないでください)。この特定のファイルのコードのみを壊すことができるので、名前の競合の原因を管理および発見するのがより簡単になります。識別子の前にstd ::(または他の任意のプレフィックス、多くの名前空間がプロジェクトに存在する可能性があります)を使用したい場合は、問題ありません。使用する識別子をグローバル名前空間に追加する場合は、問題ありません。名前空間全体を頭に入れたい場合:-)、それはあなた次第です。効果は単一のコンパイル単位に限定されますが、許容されます。


3

私としては::、なるべく利用したいです。

std::list<int> iList;

私は書くのが嫌いです:

for(std::list<int>::iterator i = iList.begin(); i != iList.end(); i++)
{
    //
}

うまくいけば、C ++ 0xで私はこれを書くでしょう:

for(auto i = iList.begin(); i != iList.end(); i++)
{
    //
}

名前空間が非常に長い場合、

namespace dir = boost::filesystem;

dir::directory_iterator file("e:/boost");
dir::directory_iterator end;

for( ; file != end; file++)
{
    if(dir::is_directory(*file))
        std::cout << *file << std::endl;
}

@AraK:名前空間dir = boost :: filesystem; これはエイリアスだと思いますか?
paoloricardo 2009

@paoloricardo:はい、その通りです。
sbi 2009

2
イテレータはでインクリメントする必要があります。定義されていても、イテレータの不要な一時コピーが作成されるためで++iはありませんi++
Felix Dombek、2011

2

using namespace stdヘッダーの名前空間スコープにいることはできません。また、私はほとんどのプログラマは、彼らが見たときに不思議に思うだろうとしvectorたりstringせずにstd::、私はないと思うので、using namespace std良いです。したがって、私は決して存在using namespace stdしないと主張します。

必要に応じて、のような宣言を使用してローカルを追加しますusing std::vector。しかし、自問してみてください:これは何に値しますか?コード行は1回(多分2回)書き込まれますが、10回、100回、または1000回読み取られます。コードを読み取る労力と比較して、using宣言またはディレクティブを追加することによる節約され​​たタイピングの労力はわずかです。

これを念頭に置いて、10年前のプロジェクトでは、すべての識別子を完全な名前空間名で明示的に修飾することにしました。最初はぎこちないと思われていたことが、2週間以内に日常的になった。現在、その会社全体のすべてのプロジェクトで、ディレクティブや宣言を使用する人はもういません。(1つの例外を除いて、以下を参照してください。)10年後のコード(いくつかのMLoC)を見て、私たちは正しい決定をしたように感じます。

通常、禁止に反対する人々は、通常、using1つのプロジェクトでそれを試していません。試したことのある人は、非常に短い時間の後にディレクティブ/宣言を使用するよりも多くの場合それを見つけます。

注:唯一の例外は、名前空間に入れることができないusing std::swapオーバーロードを取得するために(特に汎用コードで)必要なものです(この名前空間に関数のオーバーロードを入れることは許可されていないため)。swap()stdstd


3
std :: swapの特殊化は完全な特殊化です-関数テンプレートを部分的に特殊化することはできません。プログラム標準ライブラリテンプレートを部分的に特殊化することは、その特殊化がユーザー定義型に依存している限り許可されます。
CBベイリー

@チャールズ:はい、そうです、もちろんFTPSはありません。また、内でテンプレートを特化できますがstd、オーバーロードはできません。そのおならをごめんなさい。投稿を修正します。
sbi 2009

2
using namespaceディレクティブの意図はタイプすることでもなかったと思います。むしろ、それは読みやすくするためでした。なぜなら、あなたが言うように、そのコードは何十、何百、何千回も読み込まれる必要があるからです。そして、いくつかの人々のために、それは読みずっと少ないと簡単にstd::混乱。しかし、それはおそらく個人の知覚能力に帰着します。std::(セリフのように)フィルターで取り除いたり、ガイダンスのためにそれを必要とする人もいます。
Lumi、


1
@sbi:いいえ、それは客観的ではありません。それは、あなたがstd ::が役立つか、乱雑であるかどうかに依存します。よりすっきり->明快さが低下します。
ジョシュアリチャードソン

2

名前空間は、関数シグネチャの混乱汚染を防ぐためにコードを含めたままにします。

これは、適切な 名前空間の使用法の完全文書化されたデモです。

#include <iostream>
#include <cmath>  // Uses ::log, which would be the log() here if it were not in a namespace, see /programming/11892976/why-is-my-log-in-the-std-namespace

// Silently overrides std::log
//double log(double d) { return 420; }

namespace uniquename {
    using namespace std;  // So we don't have to waste space on std:: when not needed.

    double log(double d) {
        return 42;
    }

    int main() {
        cout << "Our log: " << log(4.2) << endl;
        cout << "Standard log: " << std::log(4.2);
        return 0;
    }
}

// Global wrapper for our contained code.
int main() {
    return uniquename::main();
}

出力:

Our log: 42
Standard log: 1.43508

1

using namespace stdstd現在の名前空間のコンテンツをインポートします。したがって、利点はstd::、その名前空間のすべての関数の前に入力する必要がないことです。ただし、同じ名前の関数を持つ異なる名前空間がある場合があります。したがって、必要なものを呼び出さないようにすることができます。

インポートしたいものを手動で指定stdすると、それが発生するのを防ぐことができますが、ファイルの先頭で使用リストが長くなり、開発者によっては見苦しくなります;)!

個人的には、関数を使用するたびに名前空間を指定することを好みます。ただし、名前空間が長すぎる場合は、ファイルの先頭に使用します。

編集:別の回答で述べたようにusing namespace、ヘッダーファイルを含めないでください。ヘッダーを含むすべてのファイルに伝播され、望ましくない動作が発生する可能性があります。

EDIT2:チャールズのコメントのおかげで私の答えを修正しました。


2
using namespace std;std名前空間の内容をグローバル名前空間にインポートします。デフォルトの名前空間は変更されません。グローバル名前空間で何かを定義すると、using namespace std魔法のようにstd名前空間に入れられません。
CBベイリー

すみません、これは私が意図したものではありませんでした。ご指摘いただきありがとうございます。正解します。
ウーカイ2009

1
みんな:応答をありがとう。一般に、 'using namespace std'を使用せず、潜在的な曖昧さの発生を避ける方が安全であると思われます。'std :: xxx'を使用すると、ソースファイルの先頭にさまざまな関数のリストを宣言するよりも、目的を明確に特定できるため、魅力的です。
paoloricardo 2009

1
引用(名前空間が長すぎる場合を除く)。名前空間のエイリアシングを使用すると、そこで役立ちます。'名前空間Rv1 = Thor :: XML :: XPath :: Rules :: Light :: Version1;' エイリアスに注意し、両方のスコープルールを使用してください。
マーティンヨーク

0

Javaのように、java.util。*を含めることも、各クラスを個別に選択することもできますが、スタイルによって異なります。using namespace std名前空間を汚染し、場合によっては衝突が発生し、名前空間のポイントを無効にするため、ファイル/ワイドスコープの先頭に1つは必要ないことに注意してください。しかし、多くのSTLを使用する関数がある場合、コードに混乱がusing namespace std生じ、ロジックにプレフィックス構文が入り乱れるため、おそらく(さまざまなクラスを使用する場合)または個別usingの(いくつかを使用する場合)を使用することを検討する必要があります。クラスがよくあります)。


0

使用するIDEが、必要な正確な情報を表示または非表示にするのに十分な柔軟性を備えていない限り、この議論は生き残るでしょう。

これは、コードをどのように見せたいかは、手元のタスクに依存するためです。

ソースコードの作成中、使用しているクラスを正確に確認したいのですがstd::string、それBuzFlox::Obs::stringですか、それともクラスですか?

制御フローを設計するとき、変数のタイプにさえ興味がありませんが、if's and while' s and continue'sに焦点を当てたいです。

これが私のアドバイスです:

コードの対象者とツールの能力に応じて、最も読みやすい方法またはほとんどの情報を提供する方法を選択します。


0

これを修正する方法はいくつかあります。

まず、あなたがしたように使用します。

2つ目:do namespace S = std;、2文字削減します。

3番目:を使用しますstatic

第四に:を使用する名前をstd使用しないでください。


-1

それぞれの長所と短所は何ですか

std ::を省略する唯一の理由は、理論的には、すべてのSTL関数を自分で再実装できることです。次に、コードを変更せずに、関数をstd :: vectorの使用からmy :: vectorに切り替えることができます。


名前空間は、実際には異なるが同等の機能を持つ名前の置き換えを可能にするようには設計されていません。それらは、意図しない名前の衝突を防ぐように設計されています。
マイケルバー

はい、これを壊す 'using'ディレクティブの正当な理由は、関数を新しい名前空間に切り替えることだけです。
マーティンベケット

ass名前空間の苦痛について文句を言って、usingディレクティブがない場合はウィンドウの外に捨てたいと思っているプログラマーがたくさんいると思います。私の知る限り、名前空間を使用するすべての言語には、それらを邪魔にならないようにしたいときにそれらを邪魔にならないようにするusingディレクティブに似たものがあります。ディレクティブが役に立たない場合、なぜどこにでも存在するのですか?
マイケルバー

この「使用」は、3文字入力する手間を省くためではなく、別の実装に切り替えることを目的としたものだと思います。「std :: Foo」を使用するのが好きです。これは、プログラマが通常のFooを使用しており、チェックする必要がないという契約の役割を果たすためです。「com.microsoft.visual-studio.standard-library.numbers.int foo」と入力したくないので、STLのイテレータ宣言の一部は次のようになります。Pythonは、装飾された関数または装飾されていない関数のセットをモジュールから取得できるようにする優れた機能を備えています。
マーティンベケット

-1

なぜないのか

typedef std::vector<int> ints_t;
ints_t ints1;
....
ints_t ints2;

扱いにくいの代わりに

std::vector<int> ints1;
...
std::vector<int> ints2;

私はそれがはるかに読みやすく、コーディングのための私の標準だと思います。

これを使用して、読者のための意味情報を含めることもできます。たとえば、関数のプロトタイプを考えます。

void getHistorgram(std::vector<unsigned int>&, std::vector<unsigned int>&);

戻り値はどれですか?

代わりにどうですか

typedef std::vector<unsigned int> values_t;
typedef std::vector<unsigned int> histogram_t;
...
void getHistogram(values_t&, histogram_t&); 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.