
Hello,
If the solution is>
template<typename Range> boost::sort( Range && );
I think the interesting question is really: what should boost::sort return?
Let's try to be more general. - There are read-only functions like boost::accumulate. - There are range-transforming functions, taking a range and returning a range. I think it is a discussion for a separate thread whether they are always lazy (like adaptors) or sometimes eager (boost::sort?). - And there are range-mutating functions. boost::for_each is currently an example, the range may be modified but is not returned. Many functions in application code also fall into this category. A ) We probably agree that we want to be able to stack transforming functions and use them with rvalues: adaptors::transform(adaptors::reverse( vector<int>() ), func); B) We probably also agree that a mutating function can take a transformed lvalue: vector<int> vec; for_each( adaptors::transform(vec, func), mutating_func() ); // must compile C) And we would probably prefer that a mutating function cannot take an rvalue: for_each( vector<int>(), mutating_func() ) // must not compile D) even if this rvalue is transformed: for_each( adaptors::reverse(vector<int>()), mutating_func() ) // must not compile E) Read-only functions should not be able to modify their argument, even if it is transformed: vector<int> vec; accumulate(adaptors::reverse(vec), 0, mutating_func() ) // must not compile If, as Bronek et. al. propose, - read-only functions take ranges by const&, - transforming functions take ranges by && and - mutating functions take ranges by &&, A and B and E are fulfilled. C and D are not. If, as I understand your proposal, - read-only functions take ranges by const& - transforming functions take ranges by &&, and - mutating function take by ranges &, and - t adaptors return const rvalues with range_iterator<const Range>::type mutable, A, B and C are fulfilled. D and E are not. If we change it to - read-only functions take ranges by const&, - transforming functions take ranges by &&, and - mutating function take by ranges &, and - adaptors return const rvalues with range_iterator<const Range>::type mutable _only if their input was an lvalue&_ A, B, C, and D are fulfilled, but still not E. My proposal, - read-only functions take ranges by const&, - transforming functions take ranges by &&, and - mutating function take by ranges &, and - adaptors are convertible to lvalue& if their input was an lvalue& fulfills A, B, C, D and E, but unfortunately, does not work, because it looks like when matching a template, conversion operators are not considered: struct A { operator A&() const { // should be && but unsupported return const_cast<A&>(*this); } }; void foo( A& a ){} template< class T > void bar( T& t ){} int main() { foo(A()); // ok bar(A()); // does not compile return 0; } My personal opinion is that respecting constness, E, are more important than respecting rvalueness, C and D. What do you think? Are the requirements reasonable? Any more proposals? Regards, Arno -- Dr. Arno Schödl | aschoedl@think-cell.com Technical Director think-cell Software GmbH | Chausseestr. 8/E | 10115 Berlin | Germany http://www.think-cell.com | phone +49 30 666473-10 | US phone +1 800 891 8091 Amtsgericht Berlin-Charlottenburg, HRB 85229 | European Union VAT Id DE813474306 Directors: Dr. Markus Hannebauer, Dr. Arno Schoedl