63

私が継承した一部のコードでsize_tは、std名前空間修飾子で が頻繁に使用されています。例えば:

std::size_t n = sizeof( long );

もちろん、コンパイルして正常に動作します。しかし、それは私には悪い習慣のように思えます (おそらく C から持ち越されたのでしょうか?)。

size_tC++ に組み込まれているため、グローバル名前空間に組み込まれているというのは本当ではないでしょうか? size_tC++ で使用するにはヘッダー ファイル インクルードが必要ですか?

この質問をする別の方法は、次のプログラム (インクルードなし) は、すべての C++ コンパイラでコンパイルされると予想されるかということです。

size_t foo()
{
    return sizeof( long );
}
4

8 に答える 8

135

これに関して、stackoverflowの群衆の間で混乱があるようです

::size_t下位互換性ヘッダーで定義されていstddef.hます。それは彼らの最初からANSI/ISO Cの一部でした。ISO C++すべての C++ 実装にはstddef.h(互換性)cstddefが付属している必要があり、後者のみが定義されてstd::size_tおり、必ずしも ではありません::size_t。C++ 標準の付録 D を参照してください。

于 2008-11-12T04:18:55.753 に答える
41

C++ 標準のセクション 17.4.1.2 の段落 4 には、次のように記載されています。

「ただし、C++ 標準ライブラリでは、宣言と定義 (C でマクロとして定義されている名前を除く) は、名前空間 std の名前空間スコープ (3.3.5) 内にあります。」

これには、size_t を定義するcstddefを含む、パターンcnameのヘッダーにあるアイテムが含まれます。

したがって、 std::size_t は実際には正しいです。

于 2008-10-26T02:21:18.853 に答える
13

size_tたとえば、の<stddef.h>代わりにを含めることで、グローバル名前空間に入ることができます<cstddef>。明らかな利点は見られず、この機能は非推奨です。

于 2008-10-26T11:12:02.200 に答える
4
std::size_t n = sizeof( long );

実際、あなたは上記の中で特に悪い習慣と思われるものを尋ねていません。size_tの使用、std名前空間による修飾、...

C ++標準(18.1)にあるように、size_tは標準ヘッダーで定義された型です。C言語からの継承の可能性についての考えや印象を捨てることをお勧めします。C ++は別の異なる言語であり、そのように考える方がよいでしょう。独自の標準ライブラリがあり、C++標準ライブラリのすべての要素は名前空間std内で定義されています。ただし、C++プログラムでC標準ライブラリの要素を使用することは可能です。

汚いハックとして含めることを検討したいと思います。C ++標準では、ヘッダーの内容は同じであるか、C標準ライブラリの対応するヘッダーに基づいていると記載されていますが、多くの場合、変更が適用されています。つまり、CヘッダーをC++ヘッダーに直接コピーして貼り付けることはできません。

size_tは、C++の組み込み型ではありません。これは、sizeof()の実際の戻り型が実装定義されているため、sizeof()演算子の戻り型として使用される積分型の種類を指定するために定義された型であり、C++標準はsize_tを定義することによって統合します。

次のプログラム(インクルードなし)は、すべてのC ++コンパイラでコンパイルされると予想されますか?

size_t foo()
{
    return sizeof( long );
}

C ++標準によると(1.4):

ライブラリで定義されている名前には、名前空間スコープ(7.3)があります。AC ++変換ユニット(2.1)は、適切な標準ライブラリヘッダー(16.2)を含めることにより、これらの名前へのアクセスを取得します。

size_tはstd名前空間内で定義された名前であるため、この名前を使用するすべてのプログラムには、対応するヘッダー(この場合)を含める必要があります。

次に、3.7.3の章には次のように書かれています。

ただし、std、std :: bad_alloc、およびstd :: size_tを参照すると、適切なヘッダーを含めて名前が宣言されていない限り、形式が正しくありません。

そのため、size_tを使用しているが、ヘッダーを含まないプログラムは形式が正しくありません。

于 2009-08-06T10:23:48.810 に答える
4

size_t は C++ に組み込まれていません。また、デフォルトでは定義されていません。これはGCCでコンパイルされません:

int main(int argc, char** argv) {
size_t size;
}

そうは言っても、 size_t は POSIX の一部であり、 のような基本的なものだけを使用すると<cstdlib>、最終的に定義されてしまう可能性があります。

std::size_t は size_t に相当する C++ であると主張できます。ブライアンが指摘したように、 std:: は名前空間として使用され、すべての人に適合しないグローバル変数の設定を回避します。これは std::string のようなもので、ルート名前空間で定義することもできます。

于 2008-10-26T02:18:27.130 に答える
2

他のライブラリが独自の size_t を定義する場合があります。たとえばブースト。std::size_t は、C++ 標準が確実に必要であることを指定します。

size_t は C++ 標準型であり、名前空間 std 内で定義されます。

于 2008-10-26T01:57:14.020 に答える
2

GNU コンパイラのヘッダーには次のようなものが含まれています

typedef long int __PTRDIFF_TYPE__;
typedef unsigned long int __SIZE_TYPE__;

次に、 stddef.h には次のようなものが含まれています

typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __SIZE_TYPE__ size_t;

そして最後に cstddef ファイルには次のようなものが含まれています

#include <stddef.h>

名前空間 std {

  ::ptrdiff_t; を使用します。
  ::size_t; を使用

}

明確にするべきだと思います。<cstddef> を含める限り、size_t または std::size_t のいずれかを使用できます。これは、size_t が std 名前空間の外部で型定義されてから組み込まれたためです。効果的にあなたが持っている

typedef long int ptrdiff_t;
typedef unsigned long int size_t;

名前空間 std {

  ::ptrdiff_t; を使用します。
  ::size_t; を使用

}
于 2009-04-16T04:30:09.183 に答える