在rvalue上调用begin
(和end
)是合理的,只要我们在容器被销毁后不使用生成的迭代器。但是,将右值传递给形式为T&
的参数将不起作用,这是第二次超载发挥作用的地方。
但是,它可能是,我们正在处理的前range-based for proposal wording一个轻率的改造:
添加以下的[container.concepts.member]结束:
template<Container C> concept_map Range<C> {
typedef C::iterator iterator;
iterator begin(C& c) { return Container<C>::begin(c); }
iterator end(C& c) { return Container<C>::end(c); } };
template<Container C> concept_map Range<const C> {
typedef C::const_iterator iterator;
iterator begin(const C& c) { return Container<C>::begin(c); }
iterator end(const C& c) { return Container<C>::end(c); } };
当清楚概念不会变成C++ 11时,论文被修改了,并且所有四个函数temploids可能被翻译成等价的命名空间s应付功能模板。这会导致rvalues被接受(可能是非预期的)后果,而原始代码只是为了区分不同限定的容器类型。
请注意,现代实现的begin
/end
将使用转发引用 - 例如,
template <typename T>
constexpr auto begin(T&& t)
-> decltype(std::forward<T>(t).begin()) {
return std::forward<T>(t).begin();
}
我并不确信这是故意设计。从容器中获取'begin()'而不能从同一个容器中获得'end()'看起来并不有用。 –
@ T.C。 ......除非你知道它的长度的上限。无论如何,我试图追查这篇论文。 – Columbo
当然,除了数组rvalues没有重载,它的长度实际上是在类型中,所以在调用站点中肯定是已知的。就我个人而言,我怀疑它是适应旧的[容器概念图]的一件神器(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2778.htm#container-concept- maps-container-concepts-member),它们分别使用'const_iterator'和'iterator'分别具有'const'和'nonconcon'版本。 –