C++ (在C+;+;11中)std::vector::resize(size_-type)是否适用于默认的可构造值_-type int[4]?

C++ (在C+;+;11中)std::vector::resize(size_-type)是否适用于默认的可构造值_-type int[4]?,c++,c++11,stdvector,default-constructor,C++,C++11,Stdvector,Default Constructor,在C++11中,有两个版本的std::vector::resize(): 我理解(正如对的一个答案的一个评论所建议的那样),第一个要求value\u type是默认可构造的,而第二个要求它是可复制可构造的。但是,(gcc 4.7.0) 使用名称空间std; typedef int块[4]; 载体A; 静态断言(是默认的可构造::值,;-(“”;//不激发 A.resize(100);//编译器错误 因此,要么我的理解是错误的,要么gcc是错误的。这是什么?关于向量的要求(23.3.6.3:10

在C++11中,有两个版本的
std::vector::resize()

我理解(正如对的一个答案的一个评论所建议的那样),第一个要求
value\u type
是默认可构造的,而第二个要求它是可复制可构造的。但是,(gcc 4.7.0)

使用名称空间std;
typedef int块[4];
载体A;
静态断言(是默认的可构造::值,;-(“”;//不激发
A.resize(100);//编译器错误
因此,要么我的理解是错误的,要么gcc是错误的。这是什么?

关于
向量的要求(23.3.6.3:10)。调整大小(n)
格式正确是
T
应该是
可插入的
,即以下内容应该是格式正确的(23.2.1:13):

对于数组类型无效(不能用括号初始化数组)


实际上,您认为g++有一个bug是正确的;通过提供适当的分配器,
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
}
#包括
模板结构ArrayAllocator:std::分配器{
无效构造(T(*p)[n],T(&v)[n]){
对于(int i=0;i


另一个bug存在于标准本身;20.9.4.3:3指定
std::is_default_constructible
等同于
std::is_constructible
,其中20.9.4.3:6指定
std::is_constructible
作为
T(std::declval()…)
上的格式良好标准,该标准对数组类型有效(正如@Johannes Schaub litb所指出的,数组类型可以用
(零包扩展)
初始化)。但是,17.6.3.1:2除了
T()之外,还要求
DefaultConstructible
格式良好,这不是数组类型
T
的情况,但未经
std::is_default_constructible

检查。在遇到类似的问题后,我发现resize()不适用于默认可构造类型。似乎gcc向量实现不正确

仅供参考,我针对gcc提交了一个错误:

使用此块定义:
struct block{int arr[4];};
可能重复@PiotrNycz:与
std::array
相反?@ildjarn为什么反对?它或多或少是一样的……由于我的工作“恶劣条件”,我仍然在C++03中-所以我仍然在C++03中思考;)有人应该在这里提交一份错误报告。首先,我未能理解您的
T()
。我想重要的是要提到它是
T(零包扩展)
的结果。否则,很难理解您所说的“变量定义上下文”是什么意思。但是
T(零包扩展)如果
T
是数组类型且元素类型可以值初始化,则
有效。仅
T()如果
T
是数组类型,则
格式不正确。@Johanneschaub litb谢谢,看起来这部分是标准定义的
std::is_default_constructible
中的一个错误。我问了daniel kruegler,他说他已经在做一个类似的事情(修复聚合的Defaultconstructible定义).他同意我的观点,即这种特质的结果更值得期待,语言可能应该固定为允许
ArrayType()
(特别是因为
ArrayType{}
也被允许)。我相信他会采取适当的行动。
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
allocator_traits<A>::construct(m, p, v);
::new(static_cast<void *>(p))block(v);
#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
}