不支持向量的要求

时间:2018-03-02 16:31:07

标签: c++ c++11 c++14 move noexcept

从技术上讲,noexcept指定移动c是要求向量使用移动而不是复制c' tor。

我发现GCC 7并非如此。

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

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

我想知道这是GCC问题还是编译器正常? 或者我是否误解了某些事情?

1 个答案:

答案 0 :(得分:1)

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

时使用它

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

  

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

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

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

  

备注:...如果抛出其他异常   而不是由复制构造函数,移动构造函数,赋值运算符或移动赋值运算符   T或任何InputIterator操作都没有效果。如果在插入时抛出异常   最后的单个元素TCopyInsertableis_nothrow_move_constructible<T>::value   是true,没有效果。否则,如果a的移动构造函数抛出异常   非 - CopyInsertable T,效果未指定。

*更具体地说,您的类型MoveInsertiblevector还是分配器依赖。也就是说,对于A的分配器vector,以下内容必须完整:

allocator_traits<A>::construct(m, p, rv)
  • m是您的分配器A
  • 的一个实例
  • p是指向您的类型的指针(T*)(更确切地说,它是对齐存储,可以容纳T
  • rv是我们试图插入的左值(T&&