11

C ++ 11には、次の2つのバージョンがありstd::vector::resize()ます。

void resize( size_type count );
void resize( size_type count, const value_type& value);

私は(この質問への回答の1つに対するコメントの1つで示唆されているように)、最初のものはvalue_typeデフォルトで構築可能である必要があり、2番目はコピー構築可能である必要があることを理解しています。ただし、(gcc 4.7.0)

using namespace std;
typedef int block[4];
vector<block> A;
static_assert(is_default_constructible<block>::value,";-("); //  does not fire
A.resize(100);                                               //  compiler error

したがって、私の理解が間違っているか、gccにバグがあります。どれの?

4

2 に答える 2

10

整形式であるための要件(23.3.6.3:10)vector.resize(n)は、次のようにするT必要がありますCopyInsertable。つまり、次のものが整形式である必要があります(23.2.1:13)。

allocator_traits<A>::construct(m, p, v);

ここAで、はベクトルのアロケータタイプ、mはアロケータ、pタイプはタイプT *vはタイプTです。

20.6.8.2:5からわかるように、これは呼び出しと同等であるため、一般的なケースでは配列タイプには無効です。

::new(static_cast<void *>(p))block(v);

これは配列タイプには無効です(配列は括弧で初期化できません)。


実際、g++にはバグがあるというのは正しいです。適切なアロケータを提供することで問題を回避できるはずCopyInsertableですが、g++ではこれを許可できません。

#include <vector>

template<typename T, int n> struct ArrayAllocator: std::allocator<T[n]> {
    void construct(T (*p)[n], T (&v)[n]) {
        for (int i = 0; i < n; ++i)
            ::new(static_cast<void *>(p + i)) T{v[i]};
    }
};

int main() {
    std::vector<int[4], ArrayAllocator<int, 4>> c;
    c.resize(100);  // fails

    typedef ArrayAllocator<int, 4> A;
    A m;
    int (*p)[4] = 0, v[4];
    std::allocator_traits<A>::construct(m, p, v); // works
}

もう1つのバグは、標準自体にあります。20.9.4.3:3はstd::is_default_constructible<T> 、と同等として指定しstd::is_constructible<T>ます。ここで、20.9.4.3:6はstd::is_constructible<T, Args...>、の整形式基準として指定しますT t(std::declval<Args>()...)。これは、配列タイプに有効です(@Johannes Schaub-litbが指摘しているように、配列タイプはで初期化できます(zero-pack-expansion))。ただし、17.6.3.1:2ではDefaultConstructible、さらに整形式である必要があります。T()これは、配列型には当てはまりませTんが、によってチェックされませんstd::is_default_constructible

于 2012-08-30T08:49:12.967 に答える
0

default-constructibleタイプでresize()が機能しないという同様の問題に遭遇した後、この議論を見つけました。gccベクトルの実装が正しくないようです。

参考までに、gccに対してバグを報告しました: https ://gcc.gnu.org/bugzilla/show_bug.cgi?id = 64147

于 2014-12-02T08:22:47.823 に答える