【发布时间】:2015-12-09 21:09:14
【问题描述】:
使用 c++11 和 c++14 库概念,c++ 标准库的有效实现可能会创建以概念为模板的函数的专用版本,以利用子概念的附加功能进行优化仅使用基本概念是不可能的,例如std::vector 的InputIterator 构造函数和满足RandomAccessIterator 要求的迭代器?
// 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 也是由提供的迭代器实现的概念的情况下,找到两个迭代器之间的差异将有助于 InputIterator 构造函数 std::vector,因为它允许实现预先分配所需的空间通过最终向量,而不是在构造过程中多次调整它的大小。
我可以看到它是有效的,因为标准偶尔使用 as-if 规则,例如继承层次结构中虚函数的协变返回类型。但是,情况之间存在相当明显的差异,因此我也可以看到协变返回类型背后的逻辑可能不一定已经转移到这种情况。
重申一下:c++ 标准库的有效实现是否可以创建以概念为模板的函数的专用版本,以利用子概念的附加功能进行优化,而仅使用基本概念则无法实现?
注意:我没有用c++-concepts 标记这个问题,因为据我所知,这个标签是针对Concepts-Lite 和Concepts TS,而这个问题是关于c++ 中的库概念11 和 c++14
【问题讨论】:
-
假设你有一些 RandomAccessIterators
a和b;vector(a, b)不会模棱两可吗? -
@immibis 我假设规则与模板的部分特化相同,其中更具体的函数版本会胜出。
-
成员函数是一个不好的例子,该标准已经允许实现将其签名更改为他们心中的内容,只要对标准中签名的简单调用按规定工作即可。非成员更有趣,但实现总是可以调用重载的
__helpers,而不是直接添加重载,而且如果没有 TS 的重载解析支持的概念,他们无论如何都必须这样做。 -
@T.C.但是您实际上不能将构造函数声明为
vector(RandomAccessIterator a, RandomAccessIterator b, ...),因为概念实际上并不是语言特性,对吧?你必须做template<class T> vector(T a, T b, ...)并依赖 SFINAE。 -
@immibis 正确。或者将标签分派到内部助手,这更有可能发生。无论如何,标准都要求“专门化”用于前向或更好迭代器的构造函数。
标签: c++-concepts c++ c++11 language-lawyer c++14