[Bug libstdc++/83981] New: vector::resize(size_type) should not require T to be CopyInsertable when std=c++14

dtrebbien at gmail dot com gcc-bugzilla@gcc.gnu.org
Tue Jan 23 00:04:00 GMT 2018


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83981

            Bug ID: 83981
           Summary: vector::resize(size_type) should not require T to be
                    CopyInsertable when std=c++14
           Product: gcc
           Version: 7.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dtrebbien at gmail dot com
  Target Milestone: ---

In C++14, the requirements of vector::resize(size_type) changed. Whereas C++11
requires T to be CopyInsertable, C++14 only requires T to be MoveInsertable and
DefaultInsertable.

Prompted by investigating the Stack Overflow question "boost::optional vs
std::optional for non copyable objects"
(https://stackoverflow.com/q/48340618/196844 ), it appears that there are cases
where libstdc++ requires T to be CopyInsertable when std=c++14.

Here is a test case:


#include <vector>

#include <boost/optional.hpp>

struct foo {
  foo() {}
  foo(foo&&) {}
};

int main() {
  typedef boost::optional<foo> T;
  typedef std::allocator<T> A;
  typedef std::vector<T, A> X;

  A m;
  T *p = std::allocator_traits<A>::allocate(m, 1), v;
  // DefaultInsertable
  std::allocator_traits<A>::construct(m, p),
std::allocator_traits<A>::destroy(m, p);
  // MoveInsertable
  std::allocator_traits<A>::construct(m, p, std::move(v)),
std::allocator_traits<A>::destroy(m, p);
  // CopyInsertable - not well-formed
  //std::allocator_traits<A>::construct(m, p, v),
std::allocator_traits<A>::destroy(m, p);

  X a;
  a.resize(1);

  return 0;
}


This does not compile in g++ 7.2.0, which produces the error message: "error:
use of deleted function 'constexpr foo::foo(const foo&)'". The full error
output mentions that __uninitialized_move_if_noexcept_a() is being
instantiated, which instantiates __uninitialized_copy_a(), but
__uninitialized_copy_a() does not work because T is not copyable.


More information about the Gcc-bugs mailing list