在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'版本。 –