// specified by standard vector(InputIt begin,InputIt end,const Allocator& alloc = Allocator()); // is this specialization allowed in an implementation if it provides the same functionality? vector(RandomAccessIt begin,RandomAccessIt end,const Allocator& alloc = Allocator());
这里,InputIt是满足InputIterator
概念要求的类型,RandomAccessIt满足RandomAccessIterator
的要求.值得注意的是,这个概念缺乏找到两个迭代器之间差异的要求,而它的曾孙概念RandomAccessIterator确实需要
It a,b; It::difference_type c = a - b;
有效.在RandomAccessIterator也是由提供的迭代器实现的概念的情况下,找到两个迭代器之间的差异将有助于std :: vector的InputIterator构造函数,因为它允许实现预先分配最终所需的空间.矢量,而不是在施工期间多次调整大小.
我可以看到它是有效的,因为标准偶尔使用as-if规则,例如继承层次结构中的虚函数的协变返回类型.但是,情况之间存在相当明显的差异,因此我也可以看到协变返回类型背后的逻辑可能不一定转移到这种情况.
重申一下:c标准库的有效实现是否可以创建一个概念上模板化的函数的专用版本,而单独使用基本概念是不可能的?
注意:我没有用c++-concepts标记这个问题,因为据我所知,该标签适用于Concepts-Lite和Concepts TS,这个问题是关于c 11和c 14中的库概念
解决方法
因此,矢量签名的确切细节可以在as-if规则下变化,只要可以调用指定的所有构造函数,获得的行为满足记录的特征,并且任何无效的构造函数参数仍然存在无效(因为外部代码可以执行SFINAE测试以确定给定的参数集是否构造std :: vector).
正如OP和评论所指出的,许多标准库实现只是使用标签分派来转发更高效的更专业版本.
有趣的是构造函数上下文之外的答案,您可以在其中检测具有特定签名(而不仅仅是兼容性)的函数,并且可以区分不同的函数.我不知道这里的答案,但我的(未经验证的)印象是,与标准中描述的确切签名不匹配的函数实际上有时会出现在std库中.