いつ名前をグローバル名前空間にインポートするのですか?(x :: y、x from yなどを使用)


8

私は今から約10年間、さまざまな言語でプログラミングを行っています。また、グローバルネームスペース(using x::yC ++やfrom x import yPythonなど)に何かをインポートするのが適切である場合はまだわかりません。そのため、ほとんど実行しません。

それが私が使用できる変数名のセットを制限するという理由だけでさえ、それはほとんど常に私にとって悪い考えのように思えます。例:使用する場所using namespace std;またはusing std::string;C ++でstring、変数名として使用できなくなりました(文字列ユーティリティ関数など)。

しかし、私は疑問に思っています。グローバルネームスペースに名前をインポートすることが本当に意味があるいくつかの状況はありますか?経験則はありますか?


回答:


11

C ++では、一般的に、特には眉をひそめusing namespace stdます。そのstd名前空間には非常に多くの名前があり、その多くは非常に汎用的なアルゴリズムですusing namespace std。のようなものusing std::cout;はそれほど悪くはありません。しかし、決して、usingヘッダーファイルのグローバル名前空間には何もありません。それは銃殺隊の犯罪です。


1
しかし、私の質問はどうですか?x :: yを使用する場合、またはyからxをインポートする場合
futlib

4

コードを簡略化する場合は、これを行う必要があります。名前の競合が発生する場合や、後でヘッダーファイルなどの名前の競合が発生するスコープに移動する可能性がある場合は、この操作を行わないでください。

まれだと思う人もいます。名前空間の接頭辞は、アドレスを指定するたびに誰かのフルネームを使用するなど、一般的に有用な情報を追加しないため、(ヘッダーファイル以外で)これを使用しないことはまれだと思います。

このようにしましょう。stringクラス名として表示されたら、自動的に考えるstd::stringか、mycustom::string?それは古い格言のようなものです。ひづめの音を聞くと、シマウマではなく馬だと思います。つまり、using namespace stdほとんどの場合、大したことはありません。 using namespace mycustom同様に、との競合が含まれていない限り、通常は大したことではありません。stdその場合、カスタム名前空間は、常にプレフィックスを必要とするものです。


クラスmycustomが含まれている場合はどうなりますかstring。上部にありますusing namespace mycustom;。残りのコードを通じて、現在使用していますstring。コードを読む他の誰もが、std::stringあなた(そして非常に注意深い人々)だけが考えていると考えていmycustom::stringます。ここで、シマウマを馬のパドックに入れました。また、stackoverflow.com
Martin York

1
私の最後の文を読みませんでしたか?私は特にあなたとmycustom衝突するstd場合は常にmycustom::プレフィックスを必要とするべきだと述べました。
カールビーレフェルト

やった。問題は、ほとんどの名前空間がそれほど大きくないことです。それらのすべてを知ることはさらに困難です(名前空間の将来のバージョンは拡張される可能性があります)。したがって、名前空間全体を含めることは、災害のレシピです(特定の項目を使用します(小さな特定のスコープ内で制御する方が簡単です))。コードにが含まれてdoStuff(int)いる場合。そして、の新しいバージョンでmycustomdoStuff(double)doStuff(5.5);変更の呼び出しの全体的な意味が追加されます(気付かない可能性があります)。
マーティンヨーク

3

Pythonでの作業では、インポートを参照するための明確で簡潔な名前を付けるために、常にx from y(zとして)を使用しています。

fromインポートは、深い名前空間階層を持つコードベースでは非常に貴重です。これは、コードベースのスタイル標準がPEP 8の場合に特に当てはまります。であり、行の長さが80文字未満に制限されてます。

たとえば、次のことを考慮してください。

import foo

foo.bar.baz.baf.perform_task(foo.bar.baz.quux.SOME_CONSTANT, foo.bar.alice.bob.preferred_hash_function, '42', foo.bar.magic_numbers.MY_SALT)

代わりに次のように書くことができます:

from foo.bar import baf
from foo.bar.alice import bob
from foo.bar.baz.quux import SOME_CONSTANT
from foo.bar.magic_numbers import MY_SALT

baf.perform_task(SOME_CONSTANT, bob.preferred_hash_function, '42', MY_SALT)

Pythonの識別子は大文字と小文字が区別され、長さに制限がないため、我々は関係なく、どのように多くの私たちのインポートの名前で出て実行されません。

インポートするモジュールの1つと同じ名前をモジュールで使用する場合は、インポートにエイリアスを使用できます。

from foo.bar.alice import bob as carol

def bob(x, y):
    print "running bob function"
    return carol(x, y, 42)

0

それをいつ使うかはプログラマ次第です。特にヘッダーファイルでは、これらをまったく使用しない方がよいでしょう。しかし、私がそれを使用する場合、いくつかのケースがあります

  • 別の名前空間に何かを紹介したいとき

    namespace cg
    {
      namespace details
      {
        //lots of stuff
        void some_cool_foo()
        {
          //uses a lot stuff from details, here because I don't want prefix everything with details::
        }
      }
      using details::some_cool_foo;
    }
  • 別の名前空間の一部のアルゴリズムでADLを有効にするには

    namespace n1
    {
    //some general foo
    }
    namespace n2
    {
      using n1::foo;
    //some struct
    }
    namespace n3
    {
      using n1::foo;
    //some struct
    }

.cppで名前空間の長い名前を書きたくない場合は、いつでもエイリアスを作成できます

namespace bl = boost::lambda;
namespace fs = boost::filesystem;

申し訳ありませんが、私のソースを強調することができませんでした= /
kassak
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.