我正在制作某种容器,我想模仿一个接口std::vector.但是,我很难理解构造函数重载(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());
Run Code Online (Sandbox Code Playgroud)
根据cppreference,直到C++ 11:
如果InputIt是整数类型,则此构造函数与overload(2)具有相同的效果.
我理解它是如何完成的(我认为是标签调度或模板专业化),但我不知道在C++ 11中如何实现新行为:
如果InputIt满足InputIterator,则此重载仅参与重载决策,以避免与重载(2)的歧义.
这是某种SFINAE技巧吗?我不明白SFINAE如何在这里工作.而且,既然概念或不是C++ 11(也不是C++ 14)中的东西,我不知道如何为我的容器做到这一点.
因此我的问题是:它是如何在标准库中完成的(或者至少是一个猜测),我怎样才能相对容易地为我的容器做到这一点?
它目前在标准中的措辞相当有趣.[sequence.reqmts]/P15:
实现确定类型不能是输入迭代器的程度是未指定的,除了作为最小整数类型不应该作为输入迭代器.
换句话说,实现仅测试整数类型就足够了,但如果他们愿意,他们可以做更多.
有了SFINAE友好std::iterator_traits(投票到C++ 17工作文件作为LWG问题,但可能一直由大多数实现提供),例如,有人可能测试它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());
Run Code Online (Sandbox Code Playgroud)
请注意,这只是一个概念验证.标准库中的实际实现可能是1)更复杂(例如,它可以基于迭代器类别进行优化 - 对于前向迭代器或更好,它可以一次性为所有元素分配内存)和2)甚至比这更丑陋.填充下划线以避免名称冲突.
| 归档时间: |
|
| 查看次数: |
674 次 |
| 最近记录: |