假设我想从一个数组(知道它的长度)构造一个 C++ STL 向量,即我有:
size_t length = /* ... */
int *a = new int[length];
我可以这样构造向量:
std::vector<int> v(a, a + length);
但不是这样:
std::vector<int> v(a, length);
为什么vector类没有后一种构造函数?
假设我想从一个数组(知道它的长度)构造一个 C++ STL 向量,即我有:
size_t length = /* ... */
int *a = new int[length];
我可以这样构造向量:
std::vector<int> v(a, a + length);
但不是这样:
std::vector<int> v(a, length);
为什么vector类没有后一种构造函数?
因为该构造函数是典型的begin
构造end
函数:
template< class InputIt >
vector( InputIt first, InputIt last,
const Allocator& alloc = Allocator() );
它将内容从first
to复制到last
(不包括在内)并且不获取分配的动态数组的所有权。
大多数 STL 的算法都使用[begin, end)
范围,为了保持一致性,也使用了这个构造函数。
C++ 标准库几乎总是更喜欢开始/结束对而不是开始/长度对。这种一致性是值得的。
人们通常想要“只多做一件事”,但人们非常不善于就要添加的最重要的一件事达成一致。因此,当您有一个可以完成这项工作的界面时,将其增肥以添加一个不能真正帮助很多人并且会降低一致性的 ctr 是很难推销的。
因为正如您已经指出的那样,当标准库中不需要这种代码膨胀时,现有构造函数可以很好地存在该功能。
标准容器通常在range上运行。
取指针和长度更像是 C 字符串习语;请注意,std::string
确实有这样的构造函数。
为什么vector类没有后一种构造函数?
因为那将是多余的。您已经可以在迭代器序列上构造容器(整个 stl 的设计决策一致),因此额外的构造函数不会添加任何新内容;拥有这种构造函数的唯一原因是,如果从迭代器对切换到迭代器计数对在客户端代码中是不平凡的。
描述序列的方式在 C 中被大量使用;这并不意味着它会带来好的 C++。
旁注:请不要在malloc
C++ 中使用(不在生产代码中,不在“一次编写”代码中,对于 SO 和/或其他地方的简单示例);它为其他人提供了一个糟糕的代码示例,并鼓励了使用糟糕代码的习惯。