Eggs.Variant-パヌトI

この翻蚳を公開するために、 @ encyclopedistの最近の蚘事「ファクトリヌメ゜ッド動的メモリ割り圓おなし」 に察するコメントに動機付けられたした。 この蚘事には興味がありたしたが、簡単なグヌグル怜玢では翻蚳が明らかになりたせんでした。 「無秩序。」ず思った。「C ++に関するこのような興味深い蚘事はロシア語に翻蚳されおいない。 修正する必芁がありたす。」

目次
  1. はじめに
  2. 蚭蚈
  3. 実装

  4. ただ蚀われおいないこず


Eggs.Variantの開発に関する考察 、 C ++ 11/14の䞀般的なタむプセヌフマヌクアップ結合 。

はじめに


ナニオンは、非静的メンバヌの1぀だけが䞀床に栌玍できる特別な皮類のクラスです。 最倧のメンバヌを収容するために必芁なスペヌスを占有したす。
9 [class] / 5 Unionは、 unionキヌワヌドで定矩されたクラスです。 同時に、圌はメンバヌの1人9.5のみを保持できたす。 [...]
9.5 [class.union] / 1ナニオンでアクティブにできる非静的メンバヌは1぀だけです。぀たり、ナニオン内の特定の時点では、その非静的メンバヌの1぀だけを栌玍できたす。 [...]プヌルのサむズは、その最倧の非静的メンバヌを収容するのに十分です。 各非静的メンバヌは、あたかも構造䜓の唯䞀のメンバヌであるかのようにメモリに保存されたす。 ナニオンオブゞェクトの非静的メンバヌはすべお同じアドレスを持ちたす。

オリゞナル
9 [クラス] / 5ナニオンは、クラスキヌナニオンで定矩されたクラスです。 䞀床に最倧1぀のデヌタメンバヌを保持したす9.5。 [...]
9.5 [class.union] / 1ナニオンでは、最倧で1぀の非静的デヌタメンバヌをい぀でもアクティブにできたす。぀たり、最倧で1぀の非静的デヌタメンバヌの倀をい぀でも組合。 [...]ナニオンのサむズは、最倧の非静的デヌタメンバヌを含めるのに十分です。 各非静的デヌタメンバヌは、構造䜓の唯䞀のメンバヌであるかのように割り圓おられたす。 ナニオンオブゞェクトのすべおの非静的デヌタメンバヌは同じアドレスを持ちたす。





C ++ 98では、共甚䜓メンバヌは単玔なオブゞェクト型に制限されおいたす。 これらのタむプの堎合、それらのラむフタむムは、 リポゞトリが受信されるず始たり、再利甚たたはリリヌスされるず終了したす。
3.8 [basic.life] / 1 [...]タむプTオブゞェクトのラむフタむムは、次の堎合に始たりたす。
  • タむプTアラむメントずサむズを持぀リポゞトリが取埗され、
  • オブゞェクトの初期化は、それが重芁な堎合、完了したす。

タむプTオブゞェクトのラむフタむムは、次の堎合に終了したす。
  • Tが非自明なデストラクタ12.4を持぀クラス型の堎合、デストラクタの呌び出しが開始されたす。たたは
  • オブゞェクトが占有しおいるストレヌゞが再利甚たたは解攟されたした。


オリゞナル
3.8 [basic.life] / 1 [...]タむプTオブゞェクトのラむフタむムは、次の堎合に始たりたす。
  • タむプTの適切な配眮ずサむズのストレヌゞが取埗されたす。
  • オブゞェクトに重芁な初期化がある堎合、その初期化は完了したす。

タむプTオブゞェクトのラむフタむムは、次の堎合に終了したす。
  • Tが非自明なデストラクタ12.4を持぀クラス型の堎合、デストラクタ呌び出しが開始されたす。たたは
  • オブゞェクトが占有しおいるストレヌゞは再利甚たたは解攟されたす。



この特別な保蚌により、新しい倀をア゜シ゚ヌションに割り圓おるだけでア゜シ゚ヌションのアクティブなメンバヌを倉曎でき、ストレヌゞを効果的に再利甚できるようになりたす。これは、文字ではなく、暙準の粟神でうたく䞀臎しおいたす。
さらに、ア゜シ゚ヌションはどのメンバヌがアクティブであるかを認識しないため、この情報を知らずに特別なメンバヌ機胜を実装する必芁がありたす。 ナニオンメンバは単玔な型に制限されおいるため、アクティブなメンバずは無関係に、ナニオンの基瀎ずなるバむトに関しお特別なメンバ関数を実装できたす。
9.5 [class.union] / 1 [...]非自明なコンストラクタヌ12.1、非自明なコピヌコンストラクタヌ12.8、非自明なデストラクタヌ12.4、たたは非自明なコピヌ代入挔算子 13.5.3、12.8を持぀クラスオブゞェクトはメンバヌになれたせんナニオン、たたはナニオン内にある配列芁玠。 [...]

オリゞナル
9.5 [class.union] / 1 [...]非自明なコンストラクタヌ12.1、非自明でないコピヌコンストラクタヌ12.8、非自明なデストラクタヌ12.4、たたは非-自明なコピヌ代入挔算子13.5.3、12.8は、ナニオンのメンバヌにするこずも、そのようなオブゞェクトの配列にするこずもできたせん。 [...]


C ++ 11では、この制限は削陀されたした。 ナニオンメンバは、どのタむプでも䜿甚できたす。 重芁なメンバヌを切り替えるには、珟圚のアクティブなメンバヌを明瀺的に砎棄し、 怜玢挔算子newを䜿甚しお新しいアクティブなメンバヌを䜜成する必芁がありたす。
9.5 [class.union] / 4 [泚䞀般的なケヌスでは、デストラクタの明瀺的な呌び出しを1回、ホスト挔算子new明瀺的な呌び出しを1回䜿甚しお、列挙のアクティブなメンバヌを倉曎する必芁がありたす。 -泚の終わり] [䟋タむプM非静的メンバヌmおよびタむプN n持぀列挙タむプUを持぀オブゞェクトuを考えたすN Mに非自明なデストラクタがあり、 Nに非自明なコンストラクタがある堎合たずえば、それらが宣蚀たたは仮想関数を継承する堎合、次のデストラクタの䜿甚ずnew挔算子を䜿甚しお、アクティブメンバuをmからn安党に倉曎できたす。
 um~M(); new (&u.n) N; 

-䟋の終わり]

オリゞナル
9.5 [class.union] / 4 [泚䞀般的に、ナニオンのアクティブなメンバヌを倉曎するには、明瀺的なデストラクタヌ呌び出しず新しい挔算子の配眮を䜿甚する必芁がありたす。 –泚[䟋タむプM非静的デヌタメンバヌmずタむプN nを含むナニオンタむプUオブゞェクトuを考えたすN Mに非自明なデストラクタがあり、 Nに非自明なコンストラクタがある堎合たずえば、仮想関数を宣蚀たたは継承する堎合、デストラクタず配眮new挔算子を䜿甚しお、 uのアクティブメンバをmからn安党に切り替えるこずができたす次のずおりです。
 um~M(); new (&u.n) N; 

—終わりの䟋]


関連付けのメンバヌのいずれかの特別なメンバヌ関数が自明でない堎合、関連付け自䜓の特別なメンバヌ関数は、ナヌザヌ自身によっお提䟛されない限り、暗黙的に削陀枈みずしお定矩されたす。
9.5 [class.union] / 2 [泚ナニオンの非静的メンバヌに非自明なデフォルトコンストラクタヌ12.1、コンストラクタヌのコピヌ12.8、コンストラクタヌの移動12.8、割り圓お挔算子のコピヌ12.8、割り圓お挔算子の移動12.8がある堎合たたはデストラクタ12.4の堎合、察応する組合のメンバヌ関数はナヌザヌが提䟛する必芁がありたす。そうしないず、暗黙的に組合から削陀されたす8.4.3。 —泚を終了]
9.5 [class.union] / 3 [䟋次のナニオンを怜蚎したす。
 union U { int i; float f; std::string s; }; 

std::string type21.3はすべおの特別なメンバヌ関数の非自明なバヌゞョンを宣蚀するため、デフォルトのコンストラクタヌ、コピヌ/移動コンストラクタヌ、コピヌ/移動代入挔算子、およびデストラクタヌはU型から暗黙的に削陀されたすU タむプUを䜿甚するには、これらのメンバヌ関数の䞀郚をナヌザヌが提䟛する必芁がありたす。 -䟋の終わり]

オリゞナル
9.5 [class.union] / 2 [泚ナニオンの非静的デヌタメンバヌに非自明なデフォルトコンストラクタヌ12.1、コピヌコンストラクタヌ12.8、コンストラクタヌの移動12.8、割り圓お挔算子のコピヌ12.8がある堎合、移動代入挔算子12.8、たたはデストラクタヌ12.4の堎合、ナニオンの察応するメンバヌ関数はナヌザヌが指定する必芁がありたす。そうしないず、ナニオンの暗黙的に削陀されたす8.4.3。 —泚を終了]
9.5 [class.union] / 3 [䟋次のナニオンを怜蚎したす。
 union U { int i; float f; std::string s; }; 

std::string 21.3はすべおの特別なメンバヌ関数の自明でないバヌゞョンを宣蚀するため、 Uには暗黙的に削陀されたデフォルトコンストラクタヌ、コンストラクタヌのコピヌ/移動、代入挔算子のコピヌ/移動、およびデストラクタヌがありたす。 Uを䜿甚するには、これらのメンバヌ関数の䞀郚たたはすべおをナヌザヌが提䟛する必芁がありたす。 —終わりの䟋]


これらの非自明なメンバヌ関数は、列挙のアクティブなメンバヌが枡されるように既知である堎合にのみ-通垞のセマンティクスに埓っお提䟛できたす。 マヌクされた共甚䜓は、 それ自䜓の知識を持぀共甚䜓に類䌌した共甚䜓たたはクラスです 。぀たり、珟圚アクティブなメンバヌがあればそれを知るための識別子が含たれおいたす。 マヌクされたナニオンは、その自明性に関係なく、すべおの特別なメンバヌ関数を提䟛できたす。
eggs::variant<Ts...>クラスのむンスタンスは、 eggs::variant<Ts...>型のオブゞェクトのタグ付き結合です 。 アクティブなメンバヌを切り替えるための自然なむンタヌフェむスを提䟛し、すべおの特別なメンバヌ関数に通垞のセマンティクスを提䟛したす。
 eggs::variants<N, M> u; // u     u = M{}; //    u   M u = N{}; //    u   N,      //    - using U = eggs::variants<int, float, std::string>; 


蚭蚈


蚭蚈の究極の目暙は、機胜を損なうこずなく、マヌクされたナニオンの蚭蚈を䞀般化し、改善するこずです。 ぀たり、ア゜シ゚ヌションの珟圚のアクティブなメンバヌを遞択するための特別なメンバヌが存圚しないようにするか、スペヌスをほずんど占有しないようにしたす。
 struct U { union { T0 m0; ...; TN mN; }; std::size_t which; } u; 

これに眮き換えられたす
 using V = eggs::variant<T0, ..., TN>; V v; 

特に

基本的に、むンタヌフェヌスは、メむンラむブラリの技術仕様で定矩されおいるstd::experimental::optional<T>に基づいおいたす 。 optional<T>抂念モデルは、 nullopt_t型ずT型のラベル付きナニオンで構成されたす。 optional<T>に察しお行われた蚭蚈決定は、 variant<Ts...>に簡単に転送できたす。その抂念モデルは、 nullvariant_t型ずTs背埌に隠された型のラベル付きナニオンで構成されたす。 すべおの特別なメンバヌ関数ず関連する挔算子のセマンティクス、およびアクティブなメンバヌを切り替えるためのむンタヌフェむス構築、割り圓お、たたは配眮は、 optional<T>から借甚されoptional<T> 。
アクティブなメンバヌぞのアクセスは、 std::functionスタむルで行われstd::function 。これは、タヌゲットの正しいタむプ貧しい人々のdynamic_castなどで芁求された堎合、タヌゲットぞのポむンタヌを返したす。 さらに、アクティブなメンバヌ存圚する堎合ぞのNULLポむンタヌを取埗するこずもできたす。これは、補助関数の実装を簡玠化するのに非垞に圹立぀こずが刀明したした。
最埌に、 std::tupleなどのヘルパヌクラスstd::tuple提䟛され、実行時のキャストのセマンティクスに近い非自明なセマンティクスがありたすが、むンデックスたたはタむプによる芁玠ぞのアクセスstd::tuple提䟛されたす。
参照ドキュメントはこちらにありたす 。

実装


variant<Ts>盎接実装では、基盀ずなる緩和されたナニオンをストレヌゞずしお䜿甚したす。
 template <typename ...Ts> union storage { nullvariant_t nullvariant; Ts... members; }; 

ただし、䞊蚘のコヌドは、 C ++構文の芳点からは正しくありたせん。テンプレヌトパラメヌタのセットはこのコンテキストでは展開できないためです。参照できるようにメンバヌ名を含める必芁がありたす。 代わりに、再垰的なアプロヌチを䜿甚しお、基瀎ずなるストレヌゞを構築したす。
 template <typename ...Ts> union storage; template <typename T, typename ...Ts> union storage<T, Ts...> { nullvariant_t nullvariant; T head; storage<Ts...> tail; }; template <> union storage<> { nullvariant_t nullvariant; }; 

残念ながら、これはTs型の重芁な特殊メンバヌ関数が結果ずしおリポゞトリから察応する特殊メンバヌ関数を削陀するこずを考えるず、それほど単玔ではありたせん。 この実装を䜿甚するには、少なくずもデフォルトのコンストラクタずデストラクタを結果のリストに実装する必芁がありたすが、デストラクタは有甚なこずは䜕もできたせん。
緩和された関連付けがC ++に登堎する前に䜿甚された最も単玔な実装は、 Ts任意の型の栌玍に適したベアストレヌゞを䜿甚したす-泚意、スポむラヌ堎合によっおは、動䜜したせん。 暙準には、䜜業を容易にする特別なプロパティも甚意されおいたす。
10.20.7.6 [meta.trans.other]
 template <std::size_t Len, class... Types> struct aligned_union; 

  • 条件少なくずも1぀のタむプを指定する必芁がありたす。
  • コメントメンバヌタむプごずのtypedefはPODタむプである必芁があり、 Typesリストにリストされおいるオブゞェクトの初期化されおいないストレヌゞずしお䜿甚できる。 そのサむズは少なくずもLenでなければなりたせん。 静的メンバヌalignment_valueは、 std::size_t型の敎数定数である必芁があり、その倀は、 Typesリストにリストされおいるすべおの型の最も厳密な配眮を定矩したす。


オリゞナル
10.20.7.6 [meta.trans.other]
 template <std::size_t Len, class... Types> struct aligned_union; 

  • 条件少なくずも1぀のタむプが提䟛されたす。
  • コメントメンバヌtypedefタむプは、タむプがTypesリストされおいるオブゞェクトの初期化されおいないストレヌゞずしおの䜿甚に適したPODタむプでなければなりたせん。 そのサむズは少なくずもLenでなければなりたせん。 静的メンバヌalignment_valueは、 std::size_t型の敎数定数であり、その倀はTypesリストされおいるすべおの型の䞭で最も厳密なアラむメントです。



このプロパティは、緩和されたア゜シ゚ヌションの出珟ずずもに、 䜜業ドラフトから既に削陀されおおり、珟圚では陳腐化の朜圚的な候補であるこずに泚意する必芁がありたす。 C ++ 14で可胜な代替は次のずおりです。
 template <std::size_t Len, typename ...Types> struct aligned_union { static constexpr std::size_t alignment_value = std::max({alignof(Types)...}); struct type { alignas(alignment_value) unsigned char _[std::max({Len, sizeof(Types)...})]; }; }; 

蚘憶域の型ずしおaligned_unionを䜿甚するず、 variant<Ts>簡易バヌゞョンを次のように実装できたす。
 template <typename ...Ts> class variant { template <typename T> struct _index_of { /*...*/ }; //  T  Ts...,   0 public: static constexpr std::size_t npos = std::size_t(-1); variant() noexcept : _which{npos} {} template <typename T> variant(T const& v) : _which{_index_of<T>::value} { new (target<T>()) T(v); //   T     //   new } /*...*/ std::size_t which() const noexcept { return _which; } template <typename T> T* target() noexcept { return _which == _index_of<T>::value ? static_cast<T*>(static_cast<void*>(&_storage)) : nullptr; } template <typename T> T const* target() const noexcept { return _which == _index_of<T>::value ? static_cast<T const*>(static_cast<void const*>(&_storage)) : nullptr; } private: std::size_t _which; typename std::aligned_union<0, Ts...>::type _storage; }; 

特別なメンバヌ関数は、アクティブなメンバヌ存圚する堎合にリダむレクトする必芁がありたす。 繰り返しになりたすが、この目暙を達成するためにswitchを䜿甚するこずはできたせん-これを行うこずができれば、それははるかに簡単ではありたせんが-即時眮換には再垰的な実装がありたす
 struct _destructor { template <typename T> static void call(void* ptr) { static_cast<T*>(ptr)->~T(); } }; variant<Ts...>::~variant() { apply<_destructor, Ts...>(_which, &_storage); } template <typename F> void apply(std::size_t /*which*/, void* /*storage*/) {} template <typename F, typename T, typename ...Ts> void apply(std::size_t which, void* storage) { if (which == 0) { F::template call<T>(storage); } else { apply<F, Ts...>(which - 1, storage); } } 

applyメ゜ッドの非再垰的な実装は、 switchが行う方法ず同様に、ゞャンプテヌブルを䜿甚しお構築でき、その埌に適切な゚ントリぞの遷移が続きたす。
 template <typename F, typename ...Ts> void apply(std::size_t which, void* storage) { using fun_ptr = void(*)(void*); static constexpr fun_ptr table[] = {&F::template call<Ts>...}; if (which < sizeof...(Ts)) { table[which](storage); } } 

非再垰的実装は、生成されるコヌドを高速化するだけでなく、 Tsリストに倚数の型がある堎合にコンパむルを倧幅に高速化したす-あなたの堎合、掚定倀は倉わる可胜性がありたす。

簡単にコピヌされたタむプ


簡単にコピヌされるタむプずは、その構成ビットをコピヌするこずで、぀たりstd::memcpyを䜿甚しおコピヌできるタむプです。
3.9 [basic.types] / 2簡単にコピヌされた型Tオブゞェクト基本クラスのサブオブゞェクトを陀くに察しお、型T有効な倀が含たれおいるかどうかにかかわらず、その構成バむト1.7をcharたたはunsigned char配列にコピヌできたす。 charたたはunsigned char配列の内容がオブゞェクトにコピヌされた堎合、結果ずしおオブゞェクトは元の倀を取埗するはずです。 [...]
3.9 [basic.types] / 3 T 2぀のポむンタヌobj2タむプT異なるオブゞェクトobj1およびobj2指す堎合、任意の簡単にコピヌされたタむプTに぀いお、 obj1たたはobj2いずれかが基本クラスのサブオブゞェクトであり、 obj2バむト1.7がobj2コピヌされたす、結果ずしお、 obj2はobj1ず同じ倀が含たれおいる必芁がありたす。 [...]

オリゞナル
3.9 [basic.types] / 2簡単にコピヌ可胜な型Tオブゞェクトベヌスクラスサブオブゞェクト以倖の堎合、オブゞェクトが型T有効な倀を保持しおいるかどうかにかかわらず、オブゞェクトを構成する基本バむト1.7 charたたはunsigned char配列にコピヌされたす。 charたたはunsigned char配列の内容がオブゞェクトにコピヌされた堎合、オブゞェクトは元の倀を保持したす。 [...]
3.9 [basic.types] / 3 Tぞの2぀のポむンタヌが別個のTオブゞェクトobj1ずobj2を指しおいる堎合、任意の簡単にコピヌ可胜な型Tに察しお、 obj1もobj2もベヌスクラスのサブオブゞェクトではなく、基瀎ずなるバむト1.7 obj1はobj2にコピヌされ、その埌、 obj2はobj1ず同じ倀を保持したす。 [...]


簡単にコピヌされたメンバヌの和集合自䜓は簡単にコピヌされ、远加の最適化の候補に入れられたす。これは、簡単にコピヌされたタむプでは実行できたせん。 簡単にコピヌされた型を持぀variant 、簡単にコピヌされる傟向があるはずです。
9 [クラス] / 6簡単にコピヌされたクラスは、次のクラスです
  • 自明でないコピヌコンストラクタヌはありたせん12.8、
  • 非自明な倉䜍コンストラクタヌはありたせん12.8、
  • 自明でないコピヌ割り圓お挔算子13.5.3、12.8、
  • 自明な移動代入挔算子13.5.3、12.8がなく、
  • 些现なデストラクタ12.4がありたす。

[...]

オリゞナル
9 [クラス] / 6簡単にコピヌ可胜なクラスは、次のクラスです
  • 自明でないコピヌコンストラクタはありたせん12.8、
  • 非自明な移動コンストラクタヌはありたせん12.8、
  • 自明でないコピヌ割り圓お挔算子はありたせん13.5.3、12.8、
  • 自明でない移動割り圓お挔算子はありたせん13.5.3、12.8。
  • 些现なデストラクタ12.4がありたす。

[...]


これを実珟するには、Tのすべおのタむプが簡単にコピヌされる堎合、別のvariant特殊化を遞択する必芁がありたす。 䞊蚘の特別なメンバヌ関数は、この特殊化のためにナヌザヌによっお提䟛されるべきではありたせん-それらは、デフォルトで生成されるように、それらが最初に定矩されるずきに暗黙的たたは明瀺的に指定されるべきです。 実装は、簡単な暗黙の定矩を提䟛したす。 コピヌおよび移動挔算子は、それらを含むストレヌゞビットをディスクリミネヌタヌず䞀緒に単にコピヌしたすが、デストラクタは䜕もしたせん。
ただし、1぀問題がありたす。簡単にコピヌされたクラスはたったくコピヌできない堎合がありたすが、最初に定矩されたずきに削陀された特別なメンバヌ関数は簡単です。 たずえば、 boost::noncopyableクラスの定矩方法を芋おください。
 class noncopyable { protected: constexpr noncopyable() = default; noncopyable(noncopyable const&) = delete; noncopyable& operator=(noncopyable const&) = delete; ~noncopyable() = default; }; 

std::is_trivially_copyableがnoncopyableクラスに察しおtrueを出力するのは驚きです。 さらに倧きな驚きは、コピヌできないリモヌトメンバ関数がたったく䜿甚されおいないため、 variant<noncopyable>むンスタンスを正垞にコピヌできるこずです。 実際、これは型セキュリティ違反は、型指定されおいないベアストレヌゞを䜿甚しおアクティブなメンバヌを栌玍するずいう決定に起因したす。

簡単に砎壊可胜な型


型のもう1぀の重芁なカテゎリは、 簡単に砎壊可胜な型です。
12.4 [class.dtor] / 5 [...]デストラクタは、ナヌザヌから提䟛されない堎合、および次の堎合に簡単です。
  • それは仮想ではなく、
  • 特定のクラスのすべおの盎接の基底クラスには、簡単なデストラクタがあり、
  • 型のクラスたたはクラスの配列を持぀このクラスのすべおの非静的メンバヌの堎合、そのような各クラスには簡単なデストラクタがありたす。

それ以倖の堎合、デストラクタは重芁です。

オリゞナル
12.4 [class.dtor] / 5 [...]デストラクタは、ナヌザヌが提䟛しおいない堎合、および次の堎合に簡単です。
  • デストラクタは仮想ではなく、
  • そのクラスのすべおの盎接基底クラスには簡単なデストラクタがあり、
  • クラス型たたはその配列であるそのクラスのすべおの非静的デヌタメンバに぀いお、そのような各クラスには簡単なデストラクタがありたす。

それ以倖の堎合、デストラクタは重芁です。


constexpr匏のコンテキストでむンスタンスを䜿甚できるリテラル型の芁件の1぀は、その単玔な砎壊性であるため、これは特に重芁です。
3.9 [basic.types] / 10次の堎合、型はリテラル型です。
  • [...]
  • ( 9), :
    • ,
    • (8.5.1) constexpr - ,
    • .



オリゞナル
3.9 [basic.types] / 10次の堎合、型はリテラル型です。
  • [...]
  • 次のすべおのプロパティを持぀クラス型9項
    • 取るに足らないデストラクタがあり、
    • 集玄型8.5.1であるか、少なくずも1぀のconstexprコンストラクタヌたたはコピヌたたは移動コンストラクタヌではないコンストラクタヌテンプレヌトがありたす。
    • すべおの非静的デヌタメンバヌず基本クラスは、䞍揮発性リテラルタむプです。




少なくずも1぀のメンバヌがリテラル型であり、残りのメンバヌが簡単に砎壊できる堎合、ナニオンはリテラル型にするこずができたす。したがっおvariant、これらの条件䞋では、リテラル型になるように努力する必芁がありたす。variantすべおのタむプTsが自明に砎壊可胜である堎合は、別の専門分野を遞択する必芁がありたす。ただし、定数匏の制限にはvoid、オブゞェクトぞのポむンタぞのポむンタのキャストに関する制限があるため、あたり有甚ではありたせん。
5.19 [expr.const] / 2次の匏のいずれかで抜象マシン1.9のルヌルに埓ったe蚈算eが蚈算できない堎合にのみ、条件匏は定数匏のコアになりたす。
  • [...]
  • cv void*オブゞェクトぞのポむンタヌの型から型ぞの倉換。
  • [...]


オリゞナル
5.19 [expr.const]/2 A conditional-expression e is a core constant expression unless the evaluation of e , following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
  • [...]
  • a conversion from type cv void* to a pointer-to-object type;
  • [...]



たた、型なしのrawストレヌゞを䜿甚するずいう決定により、汎甚ラベル付きプヌルの実装の完党性は、手動で実装するこずで達成できるレベルず同じレベルに制限されたす。

ただ蚀われおいないこず


生のストレヌゞに基づいた実装は、その䟡栌を正圓化したすが、氎を保持したせんが、通垞のフレヌムワヌクを超える䟡倀がありたす。䞀般化されたタむプセヌフのマヌクアップされたナニオンでの倀の保存は、通垞のナニオンでなければなりたせん。そうでない堎合、すべおの機胜を䜿甚しおも機胜したせん。

Source: https://habr.com/ru/post/J244573/


All Articles