https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89164
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> --- This version compiles even in C++11 though: #include <vector> struct X { X() = default; X(const X&) = delete; }; int main() { X x[1]; std::vector<X> v{x, x+1}; } The original version was only rejected prior to C++17 because the std::initializer_list<X> required a copy constructor, which is elided in C++17. I think the right fix is: --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -122,9 +122,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus < 201103L const bool __assignable = true; #else - // trivial types can have deleted assignment + // Trivial types can have deleted copy constructor, but std::copy + // optimization that uses memmove would happily "copy" them anyway. + static_assert(is_constructible<_ValueType2, decltype(*__first)>::value, + "result type must be constructible from value type of input range"); + typedef typename iterator_traits<_InputIterator>::reference _RefType1; typedef typename iterator_traits<_ForwardIterator>::reference _RefType2; + // Trivial types can have deleted assignment, so using std::copy + // would be ill-formed. Require assignability before using std::copy: const bool __assignable = is_assignable<_RefType2, _RefType1>::value; #endif