如何重载参数数量相同的普通函数与模板函数?vector assign实现问题
实现vector的assign()函数遇到的重载匹配问题
我的目标
我正尝试实现标准库的vector,其中有一个名为assign()的成员函数,其重载形式如下:
template<typename InputIterator> void assign(InputIterator first, InputIterator last) void assign(size_type n, const value_type& val) void assign(std::initializer_list<value_type> il)
我的实现代码
template<typename InputIterator> void assign(InputIterator first, InputIterator last) { difference_type t_ptrdiff = last - first; if(t_ptrdiff > m_size) reallocate(size_type(t_ptrdiff) << 1); for(size_type idx = 0; first != last; ++idx, ++first) m_base[idx] = *first; m_size = t_ptrdiff; } void assign(size_type n, const value_type& val) { if(n > m_size) reallocate(n << 1); for(size_type idx = 0; idx != n; ++idx) m_base[idx] = val; m_size = n; } void assign(std::initializer_list<value_type> il) { typename std::initializer_list<value_type>::size_type il_size = il.size(); typename std::initializer_list<value_type>::iterator end = il.end(); if(il_size > m_size) reallocate(il_size << 1); size_type idx = 0; for(typename std::initializer_list<value_type>::iterator begin = il.begin(); begin != end; ++idx, ++begin) m_base[idx] = *begin; m_size = il_size; }
另外,我知道当前的堆内存重新分配方式很糟糕,但这是我目前的实现:
void reallocate(size_type requested_capacity) { value_type* t_base = new value_type[requested_capacity]; m_capacity = requested_capacity; if(m_base == nullptr){ m_base = t_base; return; } if(m_capacity < m_size) m_size = m_capacity; for(size_type idx = 0; idx < m_size; ++idx) t_base[idx] = m_base[idx]; delete [] m_base; m_base = t_base; }
遇到的问题
当我使用整数对象调用这些方法时,一切都正常,例如:
vector<int> v; // 会正确调用:void assign(size_type n, const value_type& val) vector<int>::size_type n = 7; vector<int>::value_type val = 100; v.assign (n, val); // 会正确调用:void assign(InputIterator first, InputIterator last) vector<int>::iterator it = v.begin() + 1; v.assign (it, v.end()-1); // 会正确调用:void assign(std::initializer_list<value_type> il) v.assign ({1776,7,4});
但当我使用整数字面量调用assign(),比如v.assign(7, 100)时,编译器报错,因为它匹配到了模板函数void assign(InputIterator first, InputIterator last),错误信息如下:
In file included from main.cpp:LINE: vector.h: In instantiation of ‘void vector<T>::assign(InputIterator, InputIterator) [with InputIterator = int; T = int]’: main.cpp:LINE:COLUMN: required from here vector.h:LINE:COLUMN: error: invalid type argument of unary ‘*’ (have ‘int’) xxx | m_base[idx] = *first;
libstdc++实现参考
我查看了libstdc++的实现,其函数声明如下:
void assign(size_type __n, const value_type& __val); template<typename _InputIterator> void assign(_InputIterator __first, _InputIterator __last); void assign(initializer_list<value_type> __l);
标准库的std::vector不存在此冲突,v.assign(7, 100)会正确匹配到void assign(size_type __n, const value_type& __val),但我的实现却不行。
更新内容
我最近了解了std::enable_if和SFINAE,尝试的实现如下:
template<typename InputIterator> typename std::enable_if<std::is_pointer<InputIterator>::value>::type assign(InputIterator first, InputIterator last);
- 它通过
std::is_pointer检查InputIterator是否为指针,但并非所有迭代器都是指针,它们只需遵循特定规则(包括解引用、递增、可比较相等)。 - 这是我目前能做到的最优解,尽管已有示例,我仍未掌握正确的语法。
- 我将
std::enable_if<>::type用作assign()函数的返回类型,此处因为函数返回void所以没问题,但如果需要返回其他类型,正确的语法是什么? - 我的问题目前已解决,但如果有人能提供比我当前实现更优的方案,我将不胜感激!
内容的提问来源于stack exchange,提问作者akaAbdullahMateen
相关产品推荐
相关产品推荐

