14

私はc++に少し慣れておらず、すでに多くのファイルが作成されたコーディング割り当てがありますが、VS2012には次のステートメントに問題があるようです。

typedef std::uint32_t identifier;

しかし、それをに変更するようです

typedef uint32_t identifier;

エラーを取り除きます。インクルードはなく、これはヘッダーファイルにあります。定義がstdint.hにあることに気づきました。その場合、なぜこのコードはVSの外部では受け入れられる(つまり、g ++を使用して適切にコンパイルされる)のに、VSでは受け入れられないのでしょうか。誰かがこれを説明できますか?

4

2 に答える 2

16

違いは、1 つは名前空間内にあり、もう 1 つはそうでないことです。そうでなければ、それらは同じでなければなりません。1 つ目は C バージョンで、2 つ目は C++ バージョンです。C++11 より前は、C 標準ライブラリ バージョンの代わりにプレフィックス付きのバージョンを含めると、すべての C 定義が標準名前空間内に取り込まれることが義務付けられていました。C++11 では、これが常に可能であるとは限らないため、この制限は緩和されています。

コンパイラがこの型を暗黙的に定義している可能性があります。いずれにせよ、cstdint名前空間のバージョンをstd利用できるようにするために (そしておそらくグローバル名前空間のバージョンも) 含める必要があります。インクルードstdint.hすると、修飾されていないバージョンが利用可能になります。

以前のバージョンの Visual Studio はこのヘッダーなしで出荷されたため、これは問題になるはずです。

このすべての狂気のために、ほとんどの人はboost/cstdint.hpp.

編集:それらは同じであり、同じ目的を果たします。std原則として、名前空間でバージョンを使用する場合は、 cstdint. グローバル名前空間にあるものが必要な場合は、stdint.h. C++ の場合、std名前空間にあるものを使用することをお勧めします。原則として、常に使用するものを含め、他のヘッダーに依存しないでください。

于 2013-02-14T21:06:21.280 に答える
14

uint32_t(別名::uint32_t、グローバル名前空間にあるもの) は で宣言されてい<stdint.h>ます。そのヘッダー、名前空間stdで宣言することもできますstd::uint32_tが、そうする必要はありません。

std::uint32_t(つまり、名前空間にあるものstd) は で宣言されてい<cstdint>ます。そのヘッダーは、グローバル名前空間で として宣言することもでき::uint32_tますが、そうする必要はありません。

その場合、なぜこのコードは VS の外部では受け入れられる (つまり、g++ を使用して適切にコンパイルされる) のに、VS では受け入れられないのでしょうか? 誰でもこれを説明できますか?

使用したい場合はstd::uint32_t、 を実行する必要#include <cstdint>があります。そうしないと、コードがコンパイルされない可能性があります。G++ でコンパイルする場合は、おそらく他のヘッダーが間接的にインクルード<cstdint>しますが、それに依存するべきではなく、使用する名前に適切なヘッダーをインクルードしてください。

于 2013-02-14T21:19:09.710 に答える