1.自己写的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
CSDN论坛上有人回答了,解决了问题
C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。