自定义C++ Vector使用std::sort编译报错,求缺失的实现条件
自定义C++ Vector类使用std::sort编译错误解决方案
问题描述
自定义Vector类已实现迭代器,可通过范围for循环正常遍历,但调用std::sort、std::min_element、std::max_element时出现编译错误:
'_Sort_unchecked': no matching overloaded function found
std::fill可正常工作,完整代码如下:
#include <iostream> #include<exception> #include<algorithm> template <typename T> class CustomVector { private: T* m_data; int m_size ; int m_capacity ; public: class Iterator { using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; using reference = T&;; using iterator_category = std::random_access_iterator_tag; public: Iterator() = default; Iterator(T* pData) : m_ptr(pData) {} reference operator*() { return *m_ptr; } const reference& operator*() const { return *m_ptr; } pointer operator->() { return m_ptr; } const pointer operator->() const { return m_ptr; } reference operator[](int offset) { return m_ptr[offset]; } const reference operator[](int offset) const { return m_ptr[offset]; } Iterator& operator++() { ++m_ptr; return *this; } Iterator& operator--() { --m_ptr; return *this; } Iterator operator++(int) { Iterator it(*this); ++m_ptr; return *this; } Iterator operator--(int) { Iterator it(*this); --m_ptr; return *this; } Iterator& operator+=(int offset) { m_ptr += offset; return *this; } Iterator& operator-=(int offset) { m_ptr -= offset; return *this; } Iterator operator+(int offset) const { Iterator it(*this); return it += offset; } Iterator operator-(int offset) const { Iterator it(*this); return it -= offset; } difference_type operator-(const Iterator& other) const { return m_ptr - other.m_ptr; } bool operator< (const Iterator& other) const { return m_ptr < other.m_ptr; } bool operator<= (const Iterator& other) const { return m_ptr <= other.m_ptr; } bool operator> (const Iterator& other) const { return m_ptr > other.m_ptr; } bool operator>= (const Iterator& other) const { return m_ptr >= other.m_ptr; } bool operator== (const Iterator& other) const { return m_ptr == other.m_ptr; } bool operator!= (const Iterator& other) const { return m_ptr != other.m_ptr; } private: T* m_ptr{ nullptr }; }; Iterator begin() { return Iterator(m_data); } Iterator end() { return Iterator(m_data + m_size); } CustomVector() :m_size(0), m_capacity(2), m_data(new T[m_capacity]) { std::cout << "constructor called" << std::endl; } CustomVector(const int & size) { m_size = size; m_capacity = 2 * size; m_data = new T[m_capacity]; std::cout << "constructor called" << std::endl; } CustomVector(const CustomVector& other) { m_size = other.m_size; m_capacity = other.m_capacity; m_data = new T[m_capacity]; for (int i = 0; i < m_size; i++) { m_data[i] = other.m_data[i]; } } ~CustomVector() { delete[] m_data; std::cout << "destructor called" << std::endl; } int size() { return m_size; } int capacity() { return m_capacity; } void reserve(int newcapacity) { T* newData = new T[newcapacity]; for (int i = 0; i < m_size; i++) { newData[i] = m_data[i]; } if(m_data != nullptr)delete[]m_data; m_data = newData; m_capacity = newcapacity; } void push_back(const T& val) { if (m_size < m_capacity) { reserve(m_capacity * 2); } m_data[m_size++] = val; } void print_data() { Iterator iter(m_data); for (iter = this->begin(); iter != this->end(); iter++) { std::cout << "data =" << *iter << std::endl; } } void pop_back() { if (m_size > 0) { (reinterpret_cast<T*>(m_data)[m_size - 1]).~T(); m_size--; } } void clear() { if (m_size > 0) { delete[]m_data; m_data = nullptr; m_size = 0; m_capacity = 2; } } bool empty() { return (m_size == 0); } const T& operator [] (int index) const { if (index > m_size || index < 0) { throw std::out_of_range("index is out of range (Custom vector class)"); } return m_data[index]; } CustomVector<T>& operator = (const CustomVector<T>& V) { m_size = V.m_size; m_capacity = V.m_capacity; m_data = new T[m_size]; for (int i = 0; i < m_size; i++) { m_data[i] = V.m_data[i]; } } CustomVector<T>& operator>(const CustomVector<T>& other) { return *this; } CustomVector<T>& operator<(const CustomVector<T>& other) { return *this; } }; int main() { try { CustomVector<double>somevector; somevector.push_back(16666); somevector.push_back(55); somevector.push_back(100); somevector.push_back(300000); for (auto& val : somevector) { std::cout << "val = " << val << std::endl; } //double min = *std::min_element(somevector.begin(), somevector.end()); // build error //double max = *std::max_element(somevector.begin(), somevector.end()); // build error std::sort(somevector.begin(), somevector.end() ); // build error std::fill(somevector.begin(), somevector.end(), 100); // working } catch (std::exception& e) { std::cout << "exception : " << e.what() << std::endl; } return 0; }
核心问题与修复
1. 迭代器关联类型未公开
C++类默认访问权限为private,你在Iterator类中定义的迭代器关联类型(value_type、iterator_category等)处于默认的private作用域,导致std::iterator_traits无法获取这些类型信息,标准库算法(如std::sort)无法正确识别迭代器类型。
修复: 将迭代器的类型别名移至public区域:
class Iterator { public: using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; using reference = T&; using iterator_category = std::random_access_iterator_tag; // 其余迭代器方法保持不变... };
2. push_back扩容逻辑错误
当前代码中push_back的扩容条件写反,导致容器未满时就触发扩容,逻辑完全错误:
// 错误代码 if (m_size < m_capacity) { reserve(m_capacity * 2); }
修复: 当容器元素数量等于容量时才扩容:
void push_back(const T& val) { if (m_size >= m_capacity) { reserve(m_capacity * 2); } m_data[m_size++] = val; }
3. 赋值运算符缺少返回语句
operator=未返回*this,违反C++赋值运算符的常规约定,会导致未定义行为。
修复: 在赋值运算符末尾添加返回语句,同时修正内存分配的容量参数:
CustomVector<T>& operator = (const CustomVector<T>& V) { m_size = V.m_size; m_capacity = V.m_capacity; m_data = new T[m_capacity]; // 改用m_capacity保证内存容量匹配 for (int i = 0; i < m_size; i++) { m_data[i] = V.m_data[i]; } return *this; }
4. print_data字符串转义错误
代码中"data =""是HTML转义字符,应改为标准C++字符串:
void print_data() { for (auto iter = this->begin(); iter != this->end(); iter++) { std::cout << "data = " << *iter << std::endl; } }
5. 可选:添加const迭代器支持
为了让const容器也能使用标准库算法,建议添加const版本的begin()/end():
// 在CustomVector类中添加 const Iterator begin() const { return Iterator(m_data); } const Iterator end() const { return Iterator(m_data + m_size); }
修复后效果
完成上述修改后,std::sort、std::min_element、std::max_element均可正常编译运行,容器的核心逻辑也恢复正确。
内容的提问来源于stack exchange,提问作者Ziri
相关产品推荐
相关产品推荐

