2

ベクトル演算用のコンテナー クラスを作成しようとしています。オブジェクトのサイズは静的です。

template<typename T, unsigned N>
class vec{
    T data[N] = {0};
public:
    vec(std::initializer_list<T> ini){
        std::copy(ini.begin(), ini.end(), data);
    }
}

これが私が得た距離です。

しかし、比較のために std::array クラスをテストしたところ、初期化子リストが長すぎたり短すぎたりすると、どういうわけか静的アサーションを作成できることに気付きました。

std::array<float, 2> a = {1, 2, 3, 4} <- instant error message from the visual studio ide

私のクラスでは、実行時にイニシャライザ リストの長さをチェックする必要があります。

std::array クラスは、 std::initializer_list クラスを使用せずに、初期化子リスト表記でデータを直接初期化するように何らかの方法で管理していると思います。

std::array と同じ方法でクラスを初期化することは可能ですか?

4

1 に答える 1

2

std::arrayは集約であるため、集約初期化を使用します。集約の初期化中に過剰な要素を提供することは形式が正しくなく、診断が必要です。コンパイラは少なくとも警告を表示する必要があります。gcc と clang の両方がこれをエラーにします。したがって、クラスを集約にすると、std::array と同じように機能させることができます。クラス メンバーの初期化子は、C++11 ではクラスを非集合体にしますが、C++14 ではそうではないことに注意してください。

ドラフト C++11 標準セクション23.3.2.1 [array.overview]に移動すると、それが集約であることがわかります。

配列は、次の構文で初期化できる集約 (8.5.1) です。

array<T, N> a = { initializer-list };

ここで、initializer-list は、型が T に変換可能な最大 N 個の要素のコンマ区切りのリストです。

セクション8.5.1 [dcl.init.aggr]は、集計の初期化をカバーし、次のように述べています。

初期化子句の数が、初期化するメンバーまたは要素の数を超える場合、初期化子リストは不適切な形式です。

ドラフト標準は、最小限に短縮された可能な実装を説明するために次のように提供します。

template <class T, size_t N>
struct array {
    T elems[N];
};

ドラフト標準には、次のようなメモがあります。

メンバー変数 elems は、配列がクラス集約であることを強調するために、説明のためにのみ示されています。名前 elems は配列のインターフェースの一部ではありません

これは集約であり、余分な要素が提供されている場合、gcc と clang の両方でエラーが発生します。

Aggregate と POD とは何ですか?また、どのように/なぜそれらが特別なのですか?も参照してください。.

于 2015-09-15T01:53:42.430 に答える