std::allocator_traits::construct 调用了错误的构造函数
std::allocator_traits::construct invokes wrong constructor
受到 Haskell 的启发,我尝试这样实现 std::forward_list
:
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;
}
// ...
};
}
但是 push_front
中的 construct
调用复制构造函数,而不是移动构造函数。
我不明白。 construct
将转发引用作为参数,std::pair
的构造函数也是如此。所以来自 std::move
的右值引用应该原封不动地传递。那么为什么会这样呢?
(如果这是一个骗局,我很抱歉。Stack Exchange 的搜索系统没有找到它。)
原来我错误地实现了移动构造函数:
forward_list(
forward_list &&other
) : forward_list(other, other.alloc) {}
必须是:
forward_list(
forward_list &&other
) : forward_list(move(other), other.alloc) {}
受到 Haskell 的启发,我尝试这样实现 std::forward_list
:
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;
}
// ...
};
}
但是 push_front
中的 construct
调用复制构造函数,而不是移动构造函数。
我不明白。 construct
将转发引用作为参数,std::pair
的构造函数也是如此。所以来自 std::move
的右值引用应该原封不动地传递。那么为什么会这样呢?
(如果这是一个骗局,我很抱歉。Stack Exchange 的搜索系统没有找到它。)
原来我错误地实现了移动构造函数:
forward_list(
forward_list &&other
) : forward_list(other, other.alloc) {}
必须是:
forward_list(
forward_list &&other
) : forward_list(move(other), other.alloc) {}