1

ptrdiff_tこの「問題」に遭遇したとき、私は C++11 標準で遊んで読んでいました。まず、事実:

ptrdiff_t(単なる例) は、標準 C ライブラリのヘッダー<stddef.h>から<cstddef>(§18.2/2) に取り込まれます。セクション 17.6.1.2 は、C 標準ライブラリから引き出された宣言がstd名前空間内にあることを示しています。

ただし、C++ 標準ライブラリでは、宣言 (C でマクロとして定義されている名前を除く) は、名前空間の名前空間スコープ (3.3.6) 内にありますstd。これらの名前が最初にグローバル名前空間スコープ内で宣言され、次にstd明示的なusing 宣言(7.3.3) によって名前空間に挿入されるかどうかは指定されていません。

また、宣言は最初にグローバル名前空間で宣言され、次に に注入されている可能性がありますstd。したがって、私の実装では、次のものが問題なくコンパイルされることは理にかなっています。

#include <cstddef>

int main(int argc, const char* argv[])
{
  std::ptrdiff_t x;
  ptrdiff_t y;
  return 0;
}

私の実装 (gcc 4.6.3) はptrdiff_t、グローバル名前空間で宣言してから に注入する必要がありますstd。ただし、次のコードをコンパイルすると、エラーが発生します (<iostream>インクルードに注意してください)。

#include <iostream>

int main(int argc, const char* argv[])
{
  std::ptrdiff_t x;
  ptrdiff_t y;
  return 0;
}

main.cpp: 関数 'int main(int, const char**)':
main.cpp:6:3: エラー: 'ptrdiff_t' はこのスコープで宣言されていません
main.cpp:6:3: 注: 推奨される代替案:
/usr/include/c++/4.6/i686-linux-gnu/./bits/c++config.h:156:28: 注: 'std::ptrdiff_t'</p>

したがって、std::ptrdiff_tが利用可能であるため、何らかの方法<iostream>で含める必要があります (必須ではありませんが)。<cstddef>しかし、以前のようにグローバル バージョンも利用できないのはなぜですか? 実際には同じヘッダーであっても、この注入が一貫しているとは期待できませんか? これは奇妙な動作のようです。インジェクションが発生するかどうかは特定されていないかもしれませんが、両方ではなく、少なくともいずれかの方法である必要がありますよね?

4

2 に答える 2

3

特定のヘッダーで何かを宣言/定義したい場合は、それを含める必要があります。

あなたが与えた例では、g ++には実際には2つの定義がありますptrdiff_t(さらにsize_t言えば)。namespace stdに由来する最初の<bits/c++config.h>. そして、<stddef.h>(など<cstddef>)からのグローバル名前空間にあるもの。

于 2012-12-17T04:51:11.960 に答える