自己写的vector,调用移动构造函数报错

SHA-ZI 2017-09-17 09:24:28
自己写的vector,调用移动构造函数报错no matching function for call to 'vector<int>::vector(vector<int>&)'
下面是vector的实现

#include <memory>
#include <iostream>

using std::allocator;
using std::initializer_list;

template <typename T, typename A = allocator<T>>
class vector
{
A alloc;
T *elem;
size_t sz;
size_t space;

public:
vector() : sz{0}, space{0}, elem{nullptr} {};
~vector();
explicit vector(std::size_t n, const T &val = T());
explicit vector(initializer_list<T> lst);
explicit vector(const vector &vec);
explicit vector(vector &&vec);

vector &operator=(const vector &vec);
vector &operator=(vector &&vec);

// using iterator = T *;
// using const_iterator = const T *;
// iterator begin();
// const_iterator begin() const;
// reverse_iterator rbegin();
// const_reverse_iterator rbegin() const;
// reverse_iterator rend();
// const_reverse_iterator rend() const;
// const_iterator cbegin() const;
// const_iterator cend() const;
// const_reverse_iterator crbegin() const;
// const_reverse_iterator crend() const;

size_t size() { return sz; }
void resize(size_t n, const T &val = T());
size_t capacity() { return space; }
bool empty() const { return sz == 0; };
void reserve(size_t n);
void shrink_to_fit();

T &operator[](size_t i);
const T &operator[](size_t i) const;
T &at(size_t i);
const T &at(size_t i) const;
T &front() { return elem[0]; }
const T &front() const { return elem[0]; }
T &back() { return elem[sz]; }
const T &back() const { return elem[sz]; }
T *data() { return &elem[0]; }
const T *data() const { &elem[0]; }

void push_back(const T &val);
void pop_back();

void swap(vector &x);
void clear();
};

template <typename T, typename A>
vector<T, A>::vector(initializer_list<T> lst)
{
elem = alloc.allocate(lst.size());
for (int i = 0; i < lst.size(); ++i)
{
alloc.construct(&elem[i], *(lst.begin() + i));
}
sz = lst.size();
space = lst.size();
}

template <typename T, typename A>
vector<T, A>::~vector()
{
for (int i = 0; i < sz; ++i)
{
alloc.destroy(&elem[i]);
}
alloc.deallocate(elem, space);
}

template <typename T, typename A>
vector<T, A>::vector(const vector<T,A> &vec)
{
T *p = alloc.allocate(vec.sz);
for (int i = 0; i < vec.sz; ++i)
{
alloc.construct(&p[i], vec.elem[i]);
}
elem = p;
sz = vec.sz;
space = sz;
}

template <typename T, typename A>
vector<T, A>::vector( vector<T,A> &&vec) : sz{vec.sz}, space{vec.space}, elem{vec.elem}
{
vec.sz = 0;
vec.elem = nullptr;
}

template <typename T, typename A>
vector<T, A>::vector(size_t n, const T &val) : sz{n}, space{sz}
{
elem = alloc.allocate(n);
for (int i = 0; i < sz; ++i)
{
alloc.construct(&elem[i], val);
}
}

template <typename T, typename A>
vector<T, A> &vector<T, A>::operator=(const vector<T,A> &vec)
{
if (this == &vec)
{
return *this;
}
T *p = alloc.allocate(vec.sz);
for (int i = 0; i < vec.sz; ++i)
{
alloc.construct(&p[i], vec.elem[i]);
}
for (int i = 0; i < sz; ++i)
{
alloc.destroy(&elem[i]);
}
alloc.deallocate(elem, sz);

elem = p;
sz = vec.sz;
space = vec.space;
return *this;
}

template <typename T, typename A>
vector<T, A> &vector<T, A>::operator=( vector<T,A> &&vec)
{
for (int i = 0; i < sz; ++i)
{
alloc.destroy(&elem[i]);
}
alloc.deallocate(elem, sz);
elem = vec.elem;
sz = vec.sz;

vec.elem = nullptr;
vec.sz = 0;
return *this;
}

template <typename T, typename A>
void vector<T, A>::resize(size_t n, const T &val)
{
if (n < sz)
{
for (int i = n; i < sz; ++i)
{
alloc.destroy(&elem[i]);
}
sz = n;
}
else if (n > sz && n < space)
{
for (int i = sz; i < n; ++i)
{
alloc.construct(&elem[i], val);
}
sz = n;
}
else
{
T *p = alloc.allocate(n);
for (int i = 0; i < sz; ++i)
{
alloc.construct(&p[i], elem[i]);
}
for (int i = sz; i < n; ++i)
{
alloc.construct(&p[i], val);
}
sz = n;
space = n;
}
}

template <typename T, typename A>
void vector<T, A>::reserve(size_t n)
{
if (n <= space)
{
return;
}

T *p = alloc.allocate(n);
for (int i = 0; i < sz; ++i)
{
alloc.construct(&p[i], elem[i]);
}
for (int i = 0; i < sz; ++i)
{
alloc.destroy(&elem[i]);
}
alloc.deallocate(elem, space);

elem = p;
space = n;
}

template <typename T, typename A>
void vector<T, A>::shrink_to_fit()
{
T *p = alloc.allocate(sz);
for (int i = 0; i < sz; ++i)
{
alloc.construct(&p[i], elem[i]);
}

for (int i = 0; i < sz; ++i)
{
alloc.destroy(&elem[i]);
}
alloc.deallocate(elem, space);

elem = p;
space = sz;
}

template <typename T, typename A>
T &vector<T, A>::operator[](size_t n)
{
return elem[n];
}

template <typename T, typename A>
const T &vector<T, A>::operator[](size_t n) const
{
return elem[n];
}
template <typename T, typename A>
T &vector<T, A>::at(size_t n)
{
if (sz << n)
throw std::out_of_range("acess out of range exception");
return elem[n];
}

template <typename T, typename A>
const T &vector<T, A>::at(size_t n) const
{
if (sz << n)
throw std::out_of_range("acess out of range exception");
return elem[n];
}

template <typename T, typename A>
void vector<T, A>::push_back(const T &val)
{
if (sz == 0)
{
reserve(8);
}
if (sz == space)
{
reserve(2 * sz);
}
alloc.construct(&elem[sz], val);
sz++;
}

template <typename T, typename A>
void vector<T, A>::pop_back()
{
alloc.destroy(&elem[sz]);
sz--;
}

template <typename T, typename A>
void vector<T, A>::swap(vector &vec)
{
if (this != &vec)
{
size_t _size = sz;
size_t _space = space;
T *_elem = elem;

elem = vec.elem;
vec.elem = _elem;

sz = vec.sz;
vec.sz = _size;
space = vec.space;
vec.space = _space;
}
}

template <typename T, typename A>
void vector<T, A>::clear()
{
for (int i = 0; i < sz; ++i)
{
alloc.destroy(&elem[i]);
}
sz = 0;
}


下面是测试代码

#include "vector.h"
#include <iostream>
using namespace std;


vector<int> make_vec()
{
vector<int> res{1,2,3,4,5,6,7,8,9,0};
//这里按理说应该调用vector(vector&&)移动构造
return res;
}

int main()
{
std::cout<<make_vec().size()<<std::endl;

return 0;
}


下面是报错信息

c:\Users\admin\Documents\Source\Programming\chapter19\vector_test.cpp: In function 'vector<int> make_vec()':
c:\Users\admin\Documents\Source\Programming\chapter19\vector_test.cpp:10:9: error: no matching function for call to 'vector<int>::vector(vector<int>&)'
return res;
^~~
In file included from c:\Users\admin\Documents\Source\Programming\chapter19\vector_test.cpp:1:0:
c:\Users\admin\Documents\Source\Programming\chapter19\vector.h:16:2: note: candidate: vector<T, A>::vector() [with T = int; A = std::allocator<int>]
vector() : sz{0}, space{0}, elem{nullptr} {};
^~~~~~
c:\Users\admin\Documents\Source\Programming\chapter19\vector.h:16:2: note: candidate expects 0 arguments, 1 provided

请问大家这个可能是什么原因,,没思路了
...全文
280 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 版主 2017-09-18
  • 打赏
  • 举报
回复
去掉复制构造函数声明时的explicit
sdghchj 2017-09-18
  • 打赏
  • 举报
回复
理论上也是调用拷贝构造,不是复制构造,而实际上因优化的原因调用的是直接构造。
真相重于对错 2017-09-17
  • 打赏
  • 举报
回复
C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧