[Bug libstdc++/89164] can construct vector with non-copyable-but-trivially-copyable elements
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Feb 5 13:12:00 GMT 2019
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
More information about the Gcc-bugs
mailing list