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>
しかし、以前のようにグローバル バージョンも利用できないのはなぜですか? 実際には同じヘッダーであっても、この注入が一貫しているとは期待できませんか? これは奇妙な動作のようです。インジェクションが発生するかどうかは特定されていないかもしれませんが、両方ではなく、少なくともいずれかの方法である必要がありますよね?