Motivated from Haskell, I tried to implement std::forward_list
like this:
namespace std {
template <class T, class Allocator = allocator<T>>
class forward_list {
typename allocator_traits<Allocator>::template rebind_alloc<pair<forward_list<T>,T>> alloc;
typename allocator_traits<decltype(alloc)>::pointer ptr;
public:
// ...
void push_front(const T &value) {
auto newPtr = allocator_traits<decltype(alloc)>::allocate(alloc, 1);
allocator_traits<decltype(alloc)>::construct(alloc, newPtr, move(*this), value);
ptr = newPtr;
}
// ...
};
}
But the construct
in push_front
calls copy constructor, rather than move constructor.
I don't understand. construct
has forwarding references as arguments, so does the constructor of std::pair
. So the rvalue reference from std::move
should be delivered intact. So why is this happening?
(I'm sorry if this is a dupe. The searching system of Stack Exchange doesn't cut it.)
It turns out I implemented the move constructor wrongly:
forward_list(
forward_list &&other
) : forward_list(other, other.alloc) {}
It must be:
forward_list(
forward_list &&other
) : forward_list(move(other), other.alloc) {}