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

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
阅读 3.9k
1 个回答

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

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏