以下是我编写的STL样式容器的最小示例。
dynamic_matrix
template<class _Ty,
class _Alloc = std::allocator<_Ty>
> class dynamic_matrix {
public:
// PUBLIC TYPEDEFS
typedef _Ty value_type;
typedef _Alloc allocator_type;
typedef _Ty& reference;
typedef const _Ty& const_reference;
typedef std::size_t size_type;
//... other necessary typedefs...
// CONSTRUCTION/ASSIGNMENT
dynamic_matrix() : dynamic_matrix(_Alloc()) {}
explicit dynamic_matrix(const _Alloc& alloc)
: mtx(alloc), row_(0), cols_(0) {}
explicit dynamic_matrix(size_type rows, size_type cols, const _Alloc& alloc = _Alloc())
: mtx(rows*cols, alloc), rows_(rows), cols_(cols) {}
dynamic_matrix& operator=(dynamic_matrix _other) {
if (this != &_other)
swap(*this, _other);
return *this;
}
// ...
// MODIFIERS
void swap(dynamic_matrix& _other) {
mtx.swap(_other.mtx);
std::swap(rows_, _other.rows_);
std::swap(cols_, _other.cols_);
}
static void swap(dynamic_matrix& lhs, dynamic_matrix& rhs) {
lhs.swap(rhs);
}
private:
std::vector<value_type, allocator_type> mtx;
size_type rows_;
size_type cols_;
};
正如您在上面所看到的,我使用的是一个operator=
,它通过值传递dynamic_matrix
,允许编译器使用复制或移动赋值并应用相关的优化。
但是,当我查看典型STL容器(例如std::vector::operator=
和std::deque::operator=
)接口中的赋值运算符时,它们有两个重载版本 - 一个用于移动,另一个用于复制,后者使用通过const reference
而不是传递值。
那么,在为dynamic_matrix
创建赋值运算符时,我应该使用下面的版本来保持STL样式还是坚持传递值更好?
(备选dynamic_matrix::operator=
):
// copy-assign
dynamic_matrix& operator=(const dynamic_matrix& _other) {
if (this != &_other)
dynamic_matrix(_other).swap(*this);
return *this;
}
// move-assign
dynamic_matrix& operator=(dynamic_matrix&& _other) {
if (this != &_other)
swap(*this, _other);
return *this;
}
注意:我知道STL接口不是容器设计的全部和全部,但是如果我创建的容器尽可能接近STL设计那么坚持标准可能更合适。