The following program compiles only if I pass the -DA=1
flag to the compiler:
#include <iostream>
#include <vector>
#include <algorithm>
struct element {
element() = default;
element(element&&) = default;
element& operator=(element&&) = default;
element(const element&) = delete;
element& operator=(const element&) = delete;
#if A
std::vector<int> v;
#endif
};
int main() {
std::vector<element> source(10), destination;
std::move(std::begin(source), std::end(source), std::back_inserter(destination));
}
If -DA=0
is passed then compilation fails with the error:
stl_algobase.h:373:4: error: static assertion failed: type is not assignable
Check it out on Coliru.
It fails when using GCC 4.9 or Clang 3.4.
Does the presence of a member variable affect the behavior of explicitly defaulted constructors?
I was using stdlibc++ for both GCC and Clang. The code compiles when using Clang 3.4 and libc++.
This version of std::move
is:
template<class InputIterator, class OutputIterator>
OutputIterator move(InputIterator first, InputIterator last,
OutputIterator result);
OutputIterator
properties are defined by [output.iterators], in particular the following expression must be valid:
*r = o
where r
is the output iterator.
Based on the error messages shown by Coliru, it appears as if the library is checking std::is_copy_assignable<element>
, which is of course false.
This appears to be a bug; the move ought to work using the move-assignment operator.
Compare the following in the same Coliru:
int main() {
std::vector<element> e(1);
std::vector<element> d(1);
*e.begin() = std::move( *d.begin() ); // A=1 OK A=0 OK
std::move(d.begin(), d.end(), e.begin()); // A=1 OK A=0 errors
}
The definition of std::move
(3 arguments) includes that for each index it performs *(result + n) = std::move( *(first + n) );
. So if my first line is valid then my second line should also be valid.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With