web-dev-qa-db-ja.com

C ++:「typedef」または「using namespace」を使用する必要がありますか?

複数の依存モジュールを含むライブラリを書いています。別のモジュールのファイルを含める場合、名前空間を次のように解決する必要があります:

using namespace project1::namespace1;
class1 obj;

または

typedef project1::namespace1::class1 class1;
class1 obj;

各アプローチの長所/短所は何ですか? .Hファイルではtypedefを使用し、.Cファイルではusingを使用する必要があることをどこかで読みましたが、これはお勧めですか?

私が 'typedef'で遭遇した1つの問題は、元のクラスと 'typedef'を持つクラスの両方を3番目のモジュールに含めると、名前空間のあいまいさにつながることです。

40
vid

あなたが述べる2つのオプションは同等ではありません。これです:

using namespace project1::namespace1;

名前空間からeverythingを取り込むため、ほとんど制御できず、衝突が発生しやすくなります。ここには短所しかなく、長所はありません。

ただし、typedefを使用して1つのシンボルを取り込む必要はありません。

using project1::namespace1::class1;

これを使用してもtypedefを使用しても、それほど大きな違いはありません。ただし、typedefは型と列挙に限定されているのに対し、usingは値や関数などを参照できることに注意してください。

namespace X {
  const int x{42};
  enum Fruit{Apple, Pear};
}

using X::x; // OK
typedef X::x xx; // Error! 'x' in namespace 'X' does not name a type

したがって、2つの式は完全に等価ではありません。

75
juanchopanza

名前を入力しやすくするためだけにヘッダーファイルでusingまたはtypedefを使用しないでください。

ソースファイルでは、それはあなた次第です。名前全体を書き出すことは、あなたが何を意味するのか非常に明確になるため、良い習慣と考えられているようです。名前空間が長すぎる場合は、名前空間エイリアスを使用して乱雑さを減らすことができますが、意味は明確に保ちます:namespace ns = project1::namespace1;

どちらの方法でも、シンボルをグローバル名前空間にインポートする場合は、usingではなくtypedefを使用します。 typedefは、主に型を別の名前で呼び出したい場合に使用されます。これは、テンプレートであるため、何度も使用されます。たとえば、my_map の代わりに std::map<std::string, my_type>、それはまだ明確ですが、タイプする方がずっといいです。

また、この質問を参照してください: 「名前空間stdを使用する」はなぜ悪い習慣と見なされるのですか?

8
parkovski

最も明確な方法は、これらのメソッドを使用しないことです。new project1::namespace1::class1()と記述してください。

6
IProblemFactory

using project1::namespace1::class1を使用

または、ローカルスコープで使用する名前空間を制限することもできます。これは、利便性とグローバル名前空間を汚染しないための両方です。

void function()
{
    using namespace project1::namespace1;

    class1 obj;

    ...
}
3
Lyn