c++ - std::vector 构造函数采用一对迭代器

标签 c++ c++11 stl

我正在制作某种容器,我想模仿 std::vector 的界面.但是,我很难理解如何 the constructor overload (4)作品。问题是它通常与重载 (2) 冲突。

// (2)
vector(size_type count, const T& value, const Allocator& alloc = Allocator());
// (4)
template<class InputIt>
vector(InputIt first, InputIt last, const Allocator& alloc = Allocator());

根据 cppreference,C++11 之前:

this constructor has the same effect as overload (2) if InputIt is an integral type.

我了解它是如何完成的(我想是标签分派(dispatch)或模板特化),但我不知道 C++11 中的新行为是如何实现的:

This overload only participates in overload resolution if InputIt satisfies InputIterator, to avoid ambiguity with the overload (2).

这是某种 SFINAE 把戏吗?我不明白 SFINAE 怎么能在这里工作。而且,由于 C++11(也不是 C++14)中的概念与否,我不知道如何为我的容器做到这一点。

因此我的问题是:它是如何在标准库中完成的(或者至少是一个猜测),以及我如何相对容易地为我的容器完成它?

最佳答案

标准中目前的措辞方式相当有趣。 [序列.reqmts]/p15:

The extent to which an implementation determines that a type cannot be an input iterator is unspecified, except that as a minimum integral types shall not qualify as input iterators.

换句话说,实现只测试整数类型就足够了,但如果他们愿意,他们可以做更多。

与 SFINAE 友好 std::iterator_traits (作为 LWG 问题投票进入 C++17 工作文件,但可能一直由大多数实现提供),例如,可以测试 std::iterator_traits<InputIterator>::iterator_category有效并表示派生自 std::input_iterator_tag 的类型用类似的东西

template<class InputIt, std::enable_if_t<std::is_base_of<std::input_iterator_tag,
                            typename std::iterator_traits<InputIterator>::iterator_category>::value, int> = 0>
vector(InputIt first, InputIt last, const Allocator& alloc = Allocator());

请注意,这只是一个概念验证。标准库中的实际实现可能 1) 更复杂(例如,它可能基于迭代器类别进行优化 - 对于前向迭代器或更好的迭代器,它可以一次性为所有元素分配内存)和 2) 甚至比这更丑陋和填充下划线以避免名称冲突。

关于c++ - std::vector 构造函数采用一对迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28529376/

相关文章:

c++ - 将 CPU 库转换为 CUDA

c++ - std::thread 构造和执行

c++ - unordered_map 的有序版本?

c++ - C++中的连接字符串(STL)

c++ - boost::bind 何时将参数转换为所需的类型?

c++ - 在 C/C++ 中,是否有类似于 #ifndef 的指令用于 typedef?

C++ 在字符数组中查找前一个字符之后的字符

c++ - 插入 std::vector 时 std::unique_ptr 的正确用法是什么

c++ - 为什么使用局部结构作为 STL 函数参数的代码不能在 g++ 中编译?

c++ - 解锁对 STL vector::size 安全性的访问