12

union以下は簡単な例です。次のように低レベルを定義できます。

static union
{
    uint64_t a;
    uint8_t b[8];
};

しかし、このように宣言することはできませんstd::variant(構文については気にしないでください。間違っている場合は訂正してください!、アイデアをつかんでください)

std::variant<uint64_t, uint8_t[8]> v

cppReferenceは、次のことを明確に述べています。

テンプレート パラメータ

タイプ - このバリアントに格納できるタイプ。すべての型は (おそらく cv 修飾された) 非配列オブジェクト型でなければなりません

また、MSVC-v141 (C++17) コンパイラでコンパイル エラーが発生しました。

エラー C2338 バリアントでは、すべての T が非配列オブジェクト型 ([variant.variant]/2) である必要があります。


std::variantは主にクラス テンプレートであるため、 データのレイアウト/表現のみが必要なため、配列型のストレージを推測できないという問題がありますか?

4

1 に答える 1

19

アレイのサポートは、国別機関のコメント US116の後、 P0510R0で削除されました。これを以下に再現します。

代替配列のサポートが期待どおりに機能していないようです。たとえば、いずれかの選択肢が配列である場合、現在の仕様は 6 つの関係演算子すべての Requires 句を満たさず、コピー コンストラクター、移動コンストラクター、コピー代入演算子、移動を失う (オーバーロードの解決に参加しない) -代入演算子 (ただし、スワップ関数は正しく機能します)。配列の代替をアクティブにするのは困難です。私の理解では、配列を値で初期化するために引数なしで配置する必要があり、必要に応じて各要素の値を割り当てることができます。これらの問題の多くは、代わりに std::array を格納することによって配列の代替が実装された場合に解決されます。次に、説明のみの配列メンバー (std::array の) を get 関数に公開しますが、これは実験的な変更のようで、次の標準で調査する必要があります。C++17 では、次の標準で適切にサポートする自由を残すために、代わりに配列 (ただし std::array ではない) のサポートを削除する必要があります。

提案の最初の改訂中に、std::variant配列型の可能性についてはあまり考慮されていなかったようですが、参照型と無効型の場合についてはいくらか考慮さました (これらのサポートも P0510R0 で削除されました)。リビジョンのいくつかは、Destructible要件を課すことによって暗黙のうちに配列を禁止しました (これは最終的な標準テキストにはありません)。規格の草案が各国のメンバー団体に送付された後、配列は期待どおりにコピー、移動、または比較できないため、問題が生じることに誰かが気付きました。これらの問題はすべて、仕様と実装 (メンバーごとの比較など) で特殊な配列を使用することでおそらく解決できますが、この作業は標準の将来の改訂に残されました。

于 2018-03-15T06:12:30.953 に答える