重载解析如何适用于std :: vector <int> :: insert

lau*_*une 3 c++ templates

这些是insert来自std :: vector 的三个方法签名中的两个:

void insert (iterator position, size_type n, const value_type& val);
template <class InputIterator>
void insert (iterator position, InputIterator first, InputIterator last);
Run Code Online (Sandbox Code Playgroud)

现在,给定一个向量和一个插入调用,

std::vector<int> v;
v.insert( v.begin(), 3, 3 );
Run Code Online (Sandbox Code Playgroud)

怎么insert选择第一个而不是第二个?

我天真地,我确定 - 实现了相同的签名,但这里第二个(模板化)形式是由编译器选择的.

template <class T, int MAXSIZE>
class svector {
public:
  class iterator : public std::iterator<std::input_iterator_tag,T> { ... };

    // ...

  void insert (class iterator position, size_t n, const T& val){
    if( len + n > MAXSIZE ) throw std::out_of_range( "insert exceeds MAXSIZE" );
    uint32_t iPos = position - begin();
    uint32_t movlen = len - iPos + 1;
    for( uint32_t i = 0; i < movlen; i++ ){
      ele[len + n - i] = ele[len - i];
    }
    for( uint32_t i = 0; i < n; i++ ){
      ele[iPos + i] = val;
    }
    len += n;
  }

  template <class InputIterator>
  void insert (class iterator position, InputIterator first, InputIterator last){
    for( InputIterator it = first; it != last; it++ ){
      if( len + 1 > MAXSIZE ) throw std::out_of_range( "insert exceeds MAXSIZE" );
      *position = *reinterpret_cast<T*>( it );
    }
  }
Run Code Online (Sandbox Code Playgroud)

Kon*_*lph 5

您的阅读和编译器完全正确.

标准库实现必须采取预防措施(通过std::enable_if或更一般地通过SFINAE)以确保仅为迭代器类型选择第二个重载.

  • + 1,23.2.3/14:*如果表单的成员函数:[...]`rt fx1(const_iterator p,InputIterator first,InputIterator last);`[...]用类型InputIterator调用不符合输入迭代器的条件,那么这些函数不应参与重载决策.* (5认同)