1

我知道以下代码可以从数组中构建一个 stl 向量:

  // the iterator constructor can also be used to construct from arrays:
  int myints[] = {16,2,77,29};
  std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );

(来源:cppreference

使用的构造函数应该是

template <class InputIterator>
         vector (InputIterator first, InputIterator last,
                 const allocator_type& alloc = allocator_type());

如果<class InputIterator>在上面的例子中是<int>,为什么InputIterator 首先不是一个整数指针?数组名“myints”衰减为指向第一个元素的指针,因为它等价于 &myints[0]

我认为正确的版本是

template <class InputIterator>
         vector (InputIterator *first, InputIterator *last,
                 const allocator_type& alloc = allocator_type());
4

4 回答 4

6

std::vector声明如下:

template <class T, class Allocator = std::allocator<T>>
class Vector
{
  // ...
  typedef Allocator allocator_type;

  template <class InputIterator>
  vector(InputIterator first, InputIterator last,
         const allocator_type& = alocator_type());

  // ...
};

请注意,类本身和构造函数都有模板参数。创建时std::vector<int>int模板参数用于类模板参数T,确定向量元素的类型,而不是构造函数的InputIterator.

您允许InputIterator由编译器推导(实际上,必须推导构造函数的模板参数)。您将myints作为第一个参数传递给要推断的函数InputIterator。正如您所说,由于myints衰减到数组的第一个元素,因此将推断为 an并且您将获得构造函数的以下实例化:int*InputIteratorint*

vector (int* first, int* last,
        const allocator_type& alloc = allocator_type());

InputIterator不推断为int。它被推断为作为第一个参数传递的完整类型(当然,第二个参数必须匹配)。

这是有道理的,因为 anint不是有效的输入迭代器。推导的任何InputIterator内容都必须满足输入迭代器的要求。int*然而,是有效的。

于 2013-03-05T10:05:32.973 回答
4

您将向量的模板类型(int在您的情况下)与构造函数参数的模板类型混淆了。的构造函数采用-yielding-std::vector<T>类型的第一个参数。InputIteratorT

即——<class InputIterator>不是int;它是一个取消引用的迭代器int;如int*

于 2013-03-05T10:07:28.633 回答
1

这是因为迭代器并不总是指针。或者换一种说法:大多数迭代器不是指针,因此您提出的签名不适用于它们。

因此,在您的情况下,这InputIteratorint*完全可以理解的,因为迭代器的概念最初是作为“指针范围”的更广泛概念而发明的。

于 2013-03-05T10:08:24.500 回答
0

<class InputIterator>不能是<int>因为你不能取消引用(应用operator*())一个int.

于 2013-03-05T10:06:23.547 回答