3

さまざまなスタイルガイドの関連セクションを読むことを含め、宣言の使用について私が行った調査のほとんどは、すべての#includesの後に表示される限り、C++ソースファイルで宣言の使用を使用するかどうかを示しています。決定はコーダーに任されました。私が読んだスタイルガイドでさえ、一貫性を保つためにそのような一般的な論争のどちらか一方に通常は当てはまりますが、この点に関してはかなり柔軟です。

私の質問は、この高度な柔軟性を考えると、一貫したスタイルを使用することはどれほど重要ですか?たとえば、著者が次のようなものを書いたとします。

using std::vector;

vector<T> v;

std::cout << v[0] << std::endl;

std::vectorでは使用するがstd::coutまたはstd::endlでは使用しないという一貫性のないアプリケーションは、一般的に許容できると見なされますか、それとも規律がないと見なされますか?

4

5 に答える 5

7

using名前の中で一貫性のない使い方をしているのがポイントだと思います。一部のブロックで非常に頻繁に必要な名前は、using宣言を使用してローカルで宣言できますが、そうでない名前もあります。問題はありません。

名前空間スコープを持つ名前を宣言することは、常に非常に困難です。名前が特定の名前空間に属していることが明確にわかっていて、他の名前空間と混同されないようになっている場合は、コードを読みやすくするためにusing宣言を付けても問題はないと思います。

于 2010-09-27T18:29:42.540 に答える
2

私は今、名前空間を明示的に述べることを強く支持しています(つまり、「使用しない」)

ほとんどの人の名前空間の履歴は次のようになります(重要な、> 100klocプロジェクトの場合)

イノセンス->スタイル1

using namespace std;

痛い->スタイル2

using std::string;
using std::vector;

OK、もう十分です->スタイル3

std::string foo = "xxx";
于 2010-09-27T18:37:30.100 に答える
1

あなたがどこにも言わないと仮定するとusing namespace std;、私はほとんどの開発者が他の人のコードで何らかの方法で気にかけているとは思わない。それらを悩ますかもしれない唯一のことは、std ::修飾子の使いすぎです---つまり、関数で「std :: vector」を20回言っている場合は、「std::vectorを使用する」時間かもしれません。 。そうでなければ、誰も気にする必要はありません。

時々、私自身のコードでは、「std ::」修飾子を使用して、これがその識別子を使用している唯一の場所であることを示します。

于 2010-09-27T18:35:21.510 に答える
0

使わないようにしていますusing(しゃれは意図していません)。

タイピングを節約するために、私はtypedefを実行するのが好きです。

typedef std::vector< int > IntVector;
typedef std::vector< Foo > FooVector;
于 2010-09-27T18:36:11.917 に答える
0

これは、名前の一部として名前空間を常に明示的に含めることを常に提唱している他のいくつかの回答に対する対位法よりも回答ではありません。時々、これは悪い考えです。場合によっては、手元のタイプに特化した名前が存在する場合はそれを使用しますが、それ以外の場合は標準で提供される代替名を使用します。

典型的な例として、ソート関数を考えてみましょう。タイプTのオブジェクトを並べ替える場合、アイテムを交換することになります。スペシャルswap(T &, T&)が存在する場合はそれを使用しますが、template <class T> std::swapそうでない場合は使用します。

明示的に使用するスワップのフルネームを指定しようとする場合は、どちらか一方を指定する必要があります。特殊なバージョンを指定し、それ自体を定義していないタイプに対してソートをインスタンス化します。スワップは失敗します。そうでない場合は、を指定std::swapし、並べ替えるタイプ用に特別に提供されたスワップを無視します。

usingただし、このジレンマから抜け出す方法を提供します。

using namespace std;

template <class T>
mysort(/* ... */ ) {

    // ...

    if (less(x[a], x[b])
        swap(x[a], x[b]);

    // ...
}

これで、Tが見つかった名前空間にが含まれている場合、swap(T &, T&)引数依存のルックアップを介して見つけられ、上記で使用されます。存在しない場合は、表示されるようになっているstd::swapため、検出(および使用)さusing namespace std;れます。

余談ですが、ちょっとした変更を加えるだけで、using namespace x;ほぼ完全に無害にすることができると思います。現在のところ、その名前空間の名前が現在のスコープに導入されています。それらの1つがたまたま現在のスコープに存在する名前と同じである場合、競合が発生します。もちろん、問題は、名前空間に含まれるすべてを把握しているとは限らないため、ほとんどの場合、少なくともある程度の競合の可能性があることです。

using namespace x;変更は、現在のスコープを囲むスコープを作成し、その名前空間からその周囲のスコープに名前を導入したかのように扱うことです。それらの1つがたまたま現在のスコープで導入された名前と同じである場合でも、競合は発生しません。他のブロックスコープと同様に、現在のスコープの名前は周囲のスコープから同じ名前を隠します。

私はこれについてあまり詳しく考えていなかったので、解決するのにもっと注意が必要ないくつかのコーナーケースがあることは間違いありませんが、一般的な考え方はおそらく多くのことをかなり簡単にするだろうと思います。

于 2010-09-27T19:05:06.197 に答える