数组向量编译失败

Vector of array fails to compile

这个简单的程序

#include <vector>

int main()
{
    using int3 = int[3];
    std::vector<int3> vec( 2 );
}

在最新的 Visual Studio 2019 16.10.0 中没有使用 stdcpplatest 开关编译,产生错误:

>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\xutility(144,1): error C2440: 'return': cannot convert from 'int *' to '_Ty (*)'
1>        with
1>        [
1>            _Ty=int [3]
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\xutility(144,48): message : Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\xmemory(707): message : see reference to function template instantiation '_Ty (*std::construct_at<_Objty,,void>(_Ty (*const )) noexcept)[3]' being compiled
1>        with
1>        [
1>            _Ty=int [3],
1>            _Objty=int [3]
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\xmemory(1610): message : see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,>(_Alloc &,_Objty (*const ))' being compiled
1>        with
1>        [
1>            _Alloc=std::allocator<int3>,
1>            _Ty=int [3],
1>            _Objty=int [3]
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\xmemory(1611): message : see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,>(_Alloc &,_Objty (*const ))' being compiled
1>        with
1>        [
1>            _Alloc=std::allocator<int3>,
1>            _Ty=int [3],
1>            _Objty=int [3]
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\xmemory(1811): message : see reference to function template instantiation 'void std::_Uninitialized_backout_al<_Alloc>::_Emplace_back<>(void)' being compiled
1>        with
1>        [
1>            _Alloc=std::allocator<int3>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\xmemory(1811): message : see reference to function template instantiation 'void std::_Uninitialized_backout_al<_Alloc>::_Emplace_back<>(void)' being compiled
1>        with
1>        [
1>            _Alloc=std::allocator<int3>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\vector(1648): message : see reference to function template instantiation 'int (*std::_Uninitialized_value_construct_n<std::allocator<int3>>(int (*)[3],unsigned __int64,_Alloc &))[3]' being compiled
1>        with
1>        [
1>            _Alloc=std::allocator<int3>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\vector(1646): message : while compiling class template member function 'int (*std::vector<int3,std::allocator<int3>>::_Ufill(int (*)[3],const unsigned __int64,std::_Value_init_tag))[3]'
1>C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.29.30037\include\vector(493): message : see reference to function template instantiation 'int (*std::vector<int3,std::allocator<int3>>::_Ufill(int (*)[3],const unsigned __int64,std::_Value_init_tag))[3]' being compiled
1>Test.cpp(271): message : see reference to class template instantiation 'std::vector<int3,std::allocator<int3>>' being compiled
1>Done building project "Project1.vcxproj" -- FAILED.

该程序在Visual Studio 2019 16.9.5 和 gcc 11 的先前版本中编译正常,但在 clang 5 中也无法编译。 数组的 std::vector 是标准允许的还是特定于实现的行为?

来自cppreference

T - The type of the elements.

(until C++11)

T must meet the requirements of CopyAssignable and CopyConstructible.

(since C++11) (until C++17)

The requirements that are imposed on the elements depend on the actual operations performed on the container. Generally, it is required that element type is a complete type and meets the requirements of Erasable, but many member functions impose stricter requirements.

(since C++17)

The requirements that are imposed on the elements depend on the actual operations performed on the container. Generally, it is required that element type meets the requirements of Erasable, but many member functions impose stricter requirements. This container (but not its members) can be instantiated with an incomplete element type if the allocator satisfies the allocator completeness requirements.

C 数组不可 CopyAssignable 也不可 CopyConstructible。它们也不可擦除(参见 ),即使它们是可擦除的,大多数方法也需要更多。

您可以毫无问题地创建 std::array<int,3> 的向量。

PS:原则上可以编写一个自定义分配器,允许您构造一个 std::vector 的 c 数组(参见 和对该答案的评论) .不过,这主要是一种好奇心,因为你仍然相当有限。 C++11 中取消了这些要求,但是“许多成员函数提出了更严格的要求”。

你应该检查这个 answer。它会为你清除东西。

至于这个特殊情况,坚持:

std::vector<std::array<int, 3>>