不支持向量的要求

问题描述 投票:1回答:1

从技术上讲,noexcept指定move c'tor是vector要求使用move而不是copy c'tor。

我发现GCC 7的情况并非如此。

std::vector<A> v;
v.push_back(A("555"));   //triggers move c'tor

上述工作只要A实现移动c'tor并指定移动c'tor,因为noexcept不是必需的。

我想知道这是一个GCC问题还是在编译器之间是正常的? 或者是我误解了什么?

c++ c++11 c++14 move noexcept
1个回答
1
投票

该标准不需要为noexcept使用T移动构造函数,以便在调用std::vector<T>::push_back(T&&)时使用它

以下是关于push_back(T&& rv)标准的说法(参见[sequence.reqmts]):

附加rv的副本。 要求:T应该是MoveInsertable进入[vector]。

MoveInsertible是一个奇特的概念,只是意味着可以使用右值引用构造你的类型*。例如。通过移动构造函数,但通过复制构造不是不合时宜的。

我认为你将这一点与以下事实相混淆:根据移动构造函数是否被声明为noexceptstd::vector可以做出不同的异常保证。请参阅rvalue referencepush_back([vector.modifiers])的“备注”:

备注:...如果除了复制构造函数之外抛出异常,移动构造函数,赋值运算符或T的移动赋值运算符或任何InputIterator操作都没有效果。如果在末尾插入单个元素时抛出异常而TCopyInsertableis_nothrow_move_constructible<T>::valuetrue,则没有效果。否则,如果非CopyInsertable T的移动构造函数抛出异常,则效果未指定。


*更具体地说,你的类型是否是MoveInsertiblevector是否依赖于分配器。也就是说,对于你的A的分配器vector,以下必须是格式良好的:

allocator_traits<A>::construct(m, p, rv)
  • m是你的分配器A的一个实例
  • p是指向你的类型(T*)的指针(更准确地说它是可以容纳T的对齐存储)
  • rv是我们试图插入的左值(T&&
© www.soinside.com 2019 - 2024. All rights reserved.