2

namespace stdに宣言/定義を追加すると、未定義の動作が発生することは広く知られています。この規則の唯一の例外は、テンプレートの特殊化です。

次の「ハック」はどうですか?

#include <iostream>

namespace std_
{
  void Foo()
  {
    std::clog << "Hello World!" << std::endl;
  }

  using namespace std;
}

int main()
{
  namespace std = std_;

  std::Foo();
}

標準に関する限り、これは本当に明確に定義されていますか? この場合、もちろん、実際には何も追加していませんnamespace std。これをテストしたすべてのコンパイラは、これを喜んで飲み込んでいるようです。


誰かが「どうしてそんなことをするの?」に似たコメントをする前に。-- これは私の好奇心を満たすためです...

4

3 に答える 3

4

stdグローバルな宣言型リージョンにいない限り、エイリアスとして再定義しても問題ありません。

宣言領域では、namespace-alias-definition を使用して、その宣言領域で宣言された名前空間エイリアスを再定義して、それが既に参照している名前空間のみを参照することができます。

でエイリアスを定義するためmain()、グローバルstd名を隠します。これが機能する理由であり、機能するはずであり、標準に従って完全に問題ありません。名前空間には何も追加していません。stdこの「ハック」は、コードを読む人間を混乱させるだけです。

于 2010-06-27T17:55:23.353 に答える
1

の中mainで、名前空間エイリアス定義の後に、名前空間のエイリアスを参照stdします。関数のローカル変数が同じ名前のグローバル変数を隠すのと同じように、「通常の」名前空間は隠されます。stdstd_std

于 2010-06-27T17:59:22.330 に答える
0

には何も追加していませんstd::。に追加してからstd_::、という名前のエイリアスを宣言していますstd::

に追加できないルールがあるとは知りませんでしたstd::。あれは正しいですか?もしそうなら、ルールは将来の拡張のために名前空間を予約するためだけに存在すると推測しています。したがって、本当に拡張したい場合は、何もハックする必要はありませんstd::

そのようなことを許可しないコンパイラを知っている場合は、誰かが投稿してください...

于 2010-06-27T18:14:33.830 に答える