C ++のPODタイプとは何ですか?

1030
paxos1977 2008-09-29 08:36.

私はこの用語のP​​ODタイプに数回出くわしました。
どういう意味ですか?

8 answers

728
Greg Hewgill 2008-09-29 08:37.

PODは、Plain Old Dataの略です。structつまり、classコンストラクタ、デストラクタ、および仮想メンバー関数のないクラス(キーワードまたはキーワードで定義されているかどうか)です。ウィキペディアのPODに関する記事では、もう少し詳しく説明し、次のように定義しています。

C ++のプレーンな古いデータ構造は、PODSのみをメンバーとして含み、ユーザー定義のデストラクタ、ユーザー定義のコピー代入演算子、およびメンバーへのポインター型の非静的メンバーを含まない集約クラスです。

詳細については、C ++ 98/03のこの回答を参照してください。C ++ 11は、PODを取り巻くルールを変更し、それらを大幅に緩和したため、ここでフォローアップの回答が必要になりました。

367
Steve Jessop 2008-09-29 09:48.

非常に非公式:

PODは、C ++コンパイラが構造内で「魔法」が発生しないことを保証する型(クラスを含む)です。たとえば、vtablesへの非表示ポインタ、他の型にキャストされたときにアドレスに適用されるオフセット(少なくともターゲットのPODも)、コンストラクター、またはデストラクタ。大まかに言えば、タイプは、その中の唯一のものが組み込みタイプとそれらの組み合わせである場合、PODです。その結果、Cタイプのように機能します。

非公式ではない:

  • intcharwchar_tboolfloatdoubleなどあり、PODをしているlong/shortsigned/unsigned、それらのバージョン。
  • ポインター(関数へのポインターおよびメンバーへのポインターを含む)はPODであり、
  • enums PODです
  • constまたはvolatilePODは、PODです。
  • classstruct又はunion鞘のPODは、すべての非静的データメンバーであることが提供されるpublic、そしてそれは、ベースクラスなしコンストラクタ、デストラクタ、または仮想メソッドを持っていません。静的メンバーは、このルールの下で何かがPODであることを停止しません。このルールはC ++ 11で変更され、特定のプライベートメンバーが許可されています。すべてのプライベートメンバーを含むクラスをPODクラスにすることはできますか?
  • ウィキペディアは、PODがメンバーへのポインター型のメンバーを持つことができないと言うのは間違っています。むしろ、C ++ 98の表現は正しいのですが、TC1は、メンバーへのポインターがPODであることを明示しました。

正式に(C ++ 03標準):

3.9(10): "算術型(3.9.1)、列挙型、ポインター型、およびメンバー型へのポインター(3.9.2)と、これらの型のcv修飾バージョン(3.9.3)は、まとめて呼び出し元のスカラー型です。スカラータイプ、POD-structタイプ、POD-unionタイプ(9節)、そのようなタイプの配列、およびこれらのタイプのcv修飾バージョン(3.9.3)は、まとめてPODタイプと呼ばれます。

9(4):「POD-structは、タイプnon-POD-struct、non-POD-union(またはそのようなタイプの配列)または参照の非静的データメンバーを持たず、user-を持たない集約クラスです。コピー演算子を定義し、ユーザー定義のデストラクタはありません。同様に、POD-unionは、タイプnon-POD-struct、non-POD-union(またはそのようなタイプの配列)または参照の非静的データメンバーを持たない集約ユニオンです。また、ユーザー定義のコピー演算子やユーザー定義のデストラクタはありません。

8.5.1(1):「アグリゲートは配列またはクラス(9節)であり、ユーザー宣言コンストラクター(12.1)、プライベートまたは保護された非静的データメンバー(11節)、基本クラス(10節)はありません。仮想関数はありません(10.3)。」

25
ugasoft 2008-09-29 08:41.

プレーンな古いデータ

要するに、それはすべてのデータ型(例えば、内蔵されたintcharfloatlongunsigned chardouble、など)とPODデータをすべて集約。はい、それは再帰的定義です。;)

より明確にするために、PODは、私たちが「構造体」と呼ぶものです。つまり、データを格納するだけのユニットまたはユニットのグループです。

13
plugwash 2018-11-30 08:17.

なぜPODと非PODをまったく区別する必要があるのですか?

C ++はCの拡張として誕生しました。最近のC ++はもはやCの厳密なスーパーセットではありませんが、人々は依然として2つの間の高レベルの互換性を期待しています。

大まかに言えば、PODタイプは、Cと互換性があり、おそらく同様に重要なことに、特定のABI最適化と互換性があるタイプです。

Cと互換性を持たせるには、2つの制約を満たす必要があります。

  1. レイアウトは、対応するCタイプと同じである必要があります。
  2. 型は、対応するC型と同じ方法で、関数との間で受け渡しする必要があります。

特定のC ++機能はこれと互換性がありません。

仮想メソッドでは、コンパイラが仮想メソッドテーブルへの1つ以上のポインタを挿入する必要があります。これは、Cには存在しません。

ユーザー定義のコピーコンストラクター、移動コンストラクター、コピー割り当て、およびデストラクタは、パラメーターの受け渡しと戻りに影響を及ぼします。多くのCABIはレジスタで小さなパラメータを渡したり返したりしますが、ユーザー定義のコンストラクタ/割り当て/デストラクタに渡された参照はメモリ位置でのみ機能します。

したがって、「C互換」であると期待できるタイプとできないタイプを定義する必要があります。C ++ 03はこの点でやや厳しすぎました。ユーザー定義のコンストラクターは組み込みコンストラクターを無効にし、それらを追加し直そうとするとユーザー定義になり、タイプは非ポッドになります。C ++ 11は、ユーザーが組み込みコンストラクターを再導入できるようにすることで、物事をかなり開放しました。

12
набиячлэвэли 2013-12-08 11:38.

私が理解しているように、POD(PlainOldData)は単なる生データであり、次のものは必要ありません。

  • 建設される、
  • 破壊される、
  • カスタム演算子を使用します。
  • 仮想関数を持ってはいけません、
  • 演算子をオーバーライドしてはなりません。

何かがPODであるかどうかを確認する方法は?さて、それのための構造体がありますstd::is_pod

namespace std {
// Could use is_standard_layout && is_trivial instead of the builtin.
template<typename _Tp>
  struct is_pod
  : public integral_constant<bool, __is_pod(_Tp)>
  { };
}

(ヘッダーtype_traitsから)


参照:

  • http://en.cppreference.com/w/cpp/types/is_pod
  • http://en.wikipedia.org/wiki/Plain_old_data_structure
  • http://en.wikipedia.org/wiki/Plain_Old_C++_Object
  • ファイルtype_traits
11
amitabes 2016-08-17 01:56.

POD(プレーンオールドデータ)オブジェクトには、これらのデータ型の1つ(基本型、ポインター、共用体、構造体、配列、またはクラス)があり、コンストラクターはありません。逆に、非PODオブジェクトは、コンストラクターが存在するオブジェクトです。PODオブジェクトは、そのタイプに適したサイズのストレージを取得したときに存続期間を開始し、オブジェクトのストレージが再利用または割り当て解除されたときに存続期間を終了します。

PlainOldDataタイプには、次のいずれも含めることはできません。

  • 仮想関数(独自の関数または継承された関数)
  • 仮想基本クラス(直接または間接)。

PlainOldDataのより緩い定義には、コンストラクターを持つオブジェクトが含まれます。ただし、仮想的なものは除外されます。PlainOldDataタイプの重要な問題は、それらが非多型であるということです。継承はPODタイプで実行できますが、ポリモーフィズム/サブタイプではなく、ImplementationInheritance(コードの再利用)に対してのみ実行する必要があります。

一般的な(厳密には正しくありませんが)定義は、PlainOldDataタイプはVeeTableを持たないものであるというものです。

static_assertC ++ 11からC ++ 17およびPOD効果を伴うすべての非PODケースの例

std::is_pod はC ++ 11で追加されたので、今のところその標準以降について考えてみましょう。

std::is_pod で述べたようにC ++ 20から削除されます https://stackoverflow.com/a/48435532/895245 、交換のサポートが到着したら、これを更新しましょう。

標準が進化するにつれて、POD制限はますます緩和されてきました。この例では、ifdefを使用してすべての緩和をカバーすることを目指しています。

libstdc ++には、次の場所でのテストが少しあります。 https://github.com/gcc-mirror/gcc/blob/gcc-8_2_0-release/libstdc%2B%2B-v3/testsuite/20_util/is_pod/value.ccしかし、それは少なすぎます。メンテナ:この投稿を読んだら、これをマージしてください。以下で言及されているすべてのC ++テストスイートプロジェクトをチェックするのが面倒です。https://softwareengineering.stackexchange.com/questions/199708/is-there-a-compliance-test-for-c-compilers

#include <type_traits>
#include <array>
#include <vector>

int main() {
#if __cplusplus >= 201103L
    // # Not POD
    //
    // Non-POD examples. Let's just walk all non-recursive non-POD branches of cppreference.
    {
        // Non-trivial implies non-POD.
        // https://en.cppreference.com/w/cpp/named_req/TrivialType
        {
            // Has one or more default constructors, all of which are either
            // trivial or deleted, and at least one of which is not deleted.
            {
                // Not trivial because we removed the default constructor
                // by using our own custom non-default constructor.
                {
                    struct C {
                        C(int) {}
                    };
                    static_assert(std::is_trivially_copyable<C>(), "");
                    static_assert(!std::is_trivial<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // No, this is not a default trivial constructor either:
                // https://en.cppreference.com/w/cpp/language/default_constructor
                //
                // The constructor is not user-provided (i.e., is implicitly-defined or
                // defaulted on its first declaration)
                {
                    struct C {
                        C() {}
                    };
                    static_assert(std::is_trivially_copyable<C>(), "");
                    static_assert(!std::is_trivial<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }
            }

            // Not trivial because not trivially copyable.
            {
                struct C {
                    C(C&) {}
                };
                static_assert(!std::is_trivially_copyable<C>(), "");
                static_assert(!std::is_trivial<C>(), "");
                static_assert(!std::is_pod<C>(), "");
            }
        }

        // Non-standard layout implies non-POD.
        // https://en.cppreference.com/w/cpp/named_req/StandardLayoutType
        {
            // Non static members with different access control.
            {
                // i is public and j is private.
                {
                    struct C {
                        public:
                            int i;
                        private:
                            int j;
                    };
                    static_assert(!std::is_standard_layout<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // These have the same access control.
                {
                    struct C {
                        private:
                            int i;
                            int j;
                    };
                    static_assert(std::is_standard_layout<C>(), "");
                    static_assert(std::is_pod<C>(), "");

                    struct D {
                        public:
                            int i;
                            int j;
                    };
                    static_assert(std::is_standard_layout<D>(), "");
                    static_assert(std::is_pod<D>(), "");
                }
            }

            // Virtual function.
            {
                struct C {
                    virtual void f() = 0;
                };
                static_assert(!std::is_standard_layout<C>(), "");
                static_assert(!std::is_pod<C>(), "");
            }

            // Non-static member that is reference.
            {
                struct C {
                    int &i;
                };
                static_assert(!std::is_standard_layout<C>(), "");
                static_assert(!std::is_pod<C>(), "");
            }

            // Neither:
            //
            // - has no base classes with non-static data members, or
            // - has no non-static data members in the most derived class
            //   and at most one base class with non-static data members
            {
                // Non POD because has two base classes with non-static data members.
                {
                    struct Base1 {
                        int i;
                    };
                    struct Base2 {
                        int j;
                    };
                    struct C : Base1, Base2 {};
                    static_assert(!std::is_standard_layout<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // POD: has just one base class with non-static member.
                {
                    struct Base1 {
                        int i;
                    };
                    struct C : Base1 {};
                    static_assert(std::is_standard_layout<C>(), "");
                    static_assert(std::is_pod<C>(), "");
                }

                // Just one base class with non-static member: Base1, Base2 has none.
                {
                    struct Base1 {
                        int i;
                    };
                    struct Base2 {};
                    struct C : Base1, Base2 {};
                    static_assert(std::is_standard_layout<C>(), "");
                    static_assert(std::is_pod<C>(), "");
                }
            }

            // Base classes of the same type as the first non-static data member.
            // TODO failing on GCC 8.1 -std=c++11, 14 and 17.
            {
                struct C {};
                struct D : C {
                    C c;
                };
                //static_assert(!std::is_standard_layout<C>(), "");
                //static_assert(!std::is_pod<C>(), "");
            };

            // C++14 standard layout new rules, yay!
            {
                // Has two (possibly indirect) base class subobjects of the same type.
                // Here C has two base classes which are indirectly "Base".
                //
                // TODO failing on GCC 8.1 -std=c++11, 14 and 17.
                // even though the example was copy pasted from cppreference.
                {
                    struct Q {};
                    struct S : Q { };
                    struct T : Q { };
                    struct U : S, T { };  // not a standard-layout class: two base class subobjects of type Q
                    //static_assert(!std::is_standard_layout<U>(), "");
                    //static_assert(!std::is_pod<U>(), "");
                }

                // Has all non-static data members and bit-fields declared in the same class
                // (either all in the derived or all in some base).
                {
                    struct Base { int i; };
                    struct Middle : Base {};
                    struct C : Middle { int j; };
                    static_assert(!std::is_standard_layout<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // None of the base class subobjects has the same type as
                // for non-union types, as the first non-static data member
                //
                // TODO: similar to the C++11 for which we could not make a proper example,
                // but with recursivity added.

                // TODO come up with an example that is POD in C++14 but not in C++11.
            }
        }
    }

    // # POD
    //
    // POD examples. Everything that does not fall neatly in the non-POD examples.
    {
        // Can't get more POD than this.
        {
            struct C {};
            static_assert(std::is_pod<C>(), "");
            static_assert(std::is_pod<int>(), "");
        }

        // Array of POD is POD.
        {
            struct C {};
            static_assert(std::is_pod<C>(), "");
            static_assert(std::is_pod<C[]>(), "");
        }

        // Private member: became POD in C++11
        // https://stackoverflow.com/questions/4762788/can-a-class-with-all-private-members-be-a-pod-class/4762944#4762944
        {
            struct C {
                private:
                    int i;
            };
#if __cplusplus >= 201103L
            static_assert(std::is_pod<C>(), "");
#else
            static_assert(!std::is_pod<C>(), "");
#endif
        }

        // Most standard library containers are not POD because they are not trivial,
        // which can be seen directly from their interface definition in the standard.
        // https://stackoverflow.com/questions/27165436/pod-implications-for-a-struct-which-holds-an-standard-library-container
        {
            static_assert(!std::is_pod<std::vector<int>>(), "");
            static_assert(!std::is_trivially_copyable<std::vector<int>>(), "");
            // Some might be though:
            // https://stackoverflow.com/questions/3674247/is-stdarrayt-s-guaranteed-to-be-pod-if-t-is-pod
            static_assert(std::is_pod<std::array<int, 1>>(), "");
        }
    }

    // # POD effects
    //
    // Now let's verify what effects does PODness have.
    //
    // Note that this is not easy to do automatically, since many of the
    // failures are undefined behaviour.
    //
    // A good initial list can be found at:
    // https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/4178176#4178176
    {
        struct Pod {
            uint32_t i;
            uint64_t j;
        };
        static_assert(std::is_pod<Pod>(), "");

        struct NotPod {
            NotPod(uint32_t i, uint64_t j) : i(i), j(j) {}
            uint32_t i;
            uint64_t j;
        };
        static_assert(!std::is_pod<NotPod>(), "");

        // __attribute__((packed)) only works for POD, and is ignored for non-POD, and emits a warning
        // https://stackoverflow.com/questions/35152877/ignoring-packed-attribute-because-of-unpacked-non-pod-field/52986680#52986680
        {
            struct C {
                int i;
            };

            struct D : C {
                int j;
            };

            struct E {
                D d;
            } /*__attribute__((packed))*/;

            static_assert(std::is_pod<C>(), "");
            static_assert(!std::is_pod<D>(), "");
            static_assert(!std::is_pod<E>(), "");
        }
    }
#endif
}

GitHubアップストリーム。

テスト済み:

for std in 11 14 17; do echo $std; g++-8 -Wall -Werror -Wextra -pedantic -std=c++$std pod.cpp; done

Ubuntu 18.04、GCC8.2.0で。

5
ThomasMcLeod 2018-01-25 18:09.

PODの概念とタイプ特性std::is_podは、C ++ 20で非推奨になります。詳細については、この質問を参照してください。

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

アトランタのドナ・ブラジル:「私があなたに私の話をするとき私を踏まないでください」

アトランタのドナ・ブラジル:「私があなたに私の話をするとき私を踏まないでください」

2017年11月19日にアトランタで開催されたドナブラジルとモーアイボリー(ダグスミスフォトグラフィー)ドナブラジルを見逃すことはありません。

彼らは北朝鮮から脱出した亡命者の胃の中に奇妙な寄生虫を見つけました

彼らは北朝鮮から脱出した亡命者の胃の中に奇妙な寄生虫を見つけました

画像:ゲッティ陰謀愛好家は新しくてエキサイティングなディスカッション資料を持っています:国境を越えて韓国に5発撃たれた北朝鮮の脱北者は寄生虫でいっぱいで、そのうちの1人は南のメディアは、寄生虫を持った北朝鮮の脱北者を見つけることは珍しいことではないと報告している、実際、男性が30以上のタイプを持っていたケースがあった。

パニッシャーの第2話は、複雑な陰謀の網を織り交ぜています

パニッシャーの第2話は、複雑な陰謀の網を織り交ぜています

写真:パニッシャー(Netflix)これらのMarvel Netflixが愛していることが1つあるとすれば、それは複雑な政府や企業の陰謀です。そして、なぜこれらのショーがそのルートを選択するのかを理解するのは簡単です。

最新のBoseヘッドフォンは音楽を聴くためのものではなく、パートナーの鼻を鳴らすためのものです。

最新のBoseヘッドフォンは音楽を聴くためのものではなく、パートナーの鼻を鳴らすためのものです。

あなたのパートナーはチェーンソーのように詮索し、あなたを眠らせませんか?あなたのパートナーはあなたがチェーンソーのように詮索したと主張しますが、あなたが詮索しないので彼らは彼の想像ですか?あなたのケースが何であれ、Bose(はい、ハイエンドオーディオ機器のメーカー)はあなたのために何かを持っています。それらはBoseSleepbudsと呼ばれます。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language