[range] What's the best way to initialize a new container from a range?

Hi! Say I have a range R and I want to construct a new container from the range R. Will I always have to repeat the expression yielding the range, or is there a shorter way? Example: std::vector<int> numbers( boost::irange(7, 42).begin(), boost::irange(7, 42).end() ); Note that it's just an example. Is it possible to create a container C from a range expression R in one step? Any helper function for this? cheers, Martin

Hi! On Fri, Aug 26, 2011 at 2:30 PM, Martin B. <0xCDCDCDCD@gmx.at> wrote:
Hi!
Say I have a range R and I want to construct a new container from the range R. Will I always have to repeat the expression yielding the range, or is there a shorter way?
Example:
std::vector<int> numbers( boost::irange(7, 42).begin(), boost::irange(7, 42).end() );
Note that it's just an example.
Is it possible to create a container C from a range expression R in one step? Any helper function for this?
What about that:
#include

On 26.08.2011 20:21, Ovanes Markarian wrote:
On Fri, Aug 26, 2011 at 2:30 PM, Martin B. <0xCDCDCDCD@gmx.at mailto:0xCDCDCDCD@gmx.at> wrote:
Hi!
Say I have a range R and I want to construct a new container from the range R. Will I always have to repeat the expression yielding the range, or is there a shorter way?
Example:
std::vector<int> numbers( boost::irange(7, 42).begin(), boost::irange(7, 42).end() );
Note that it's just an example.
Is it possible to create a container C from a range expression R in one step? Any helper function for this?
What about that: ... integer_range<int> ir=irange(7,42); vector<int> numbers(ir.begin(), ir.end());
For this to work I need the exact type of the range, which can be quite
annoying as far as I could tell. (Plus, I *don't want* to care what type
of the range is.)
Really, if I had C++11/auto, I wouldn't mind so much, i.e.
auto xr = get_some_range(...);
vector<int> numbers(xr.begin(), xr.end());
but I don't have an `auto` capable compiler, so spelling out the range
type for this is really crappy.
Writing a make_container function seems fiddly wrt. to the C++03
reference type of the passed range, but maybe someone can help:
template

2011/8/29 Martin B. <0xCDCDCDCD@gmx.at>:
On 26.08.2011 20:21, Ovanes Markarian wrote:
On Fri, Aug 26, 2011 at 2:30 PM, Martin B. <0xCDCDCDCD@gmx.at mailto:0xCDCDCDCD@gmx.at> wrote:
Hi!
Say I have a range R and I want to construct a new container from the range R. Will I always have to repeat the expression yielding the range, or is there a shorter way?
I do something like this:
template <class SinglePassRange>
boost::container::vector

On 29.08.2011 14:41, Szymon Gatner wrote:
2011/8/29 Martin B.<0xCDCDCDCD@gmx.at>:
On 26.08.2011 20:21, Ovanes Markarian wrote:
On Fri, Aug 26, 2011 at 2:30 PM, Martin B.<0xCDCDCDCD@gmx.at mailto:0xCDCDCDCD@gmx.at> wrote:
Hi!
Say I have a range R and I want to construct a new container from the range R. Will I always have to repeat the expression yielding the range, or is there a shorter way?
I do something like this:
... { ... v(boost::begin(rng), boost::end(rng));
return move(v); }
and using it surprisingly often as move semantics allow for cheap return-by-value
That code is wrong. (As far as I understand C++11.) AFAIK, you should *never*(?) explicitly move the return value as: * The compiler is free to do so anyway. (AFAIK) * It will prevent RVO. (AFAIK) so I would just leave the move and do a `return v;` relying on the fact that even my C++03 my compiler will do RVO and in-place construction of the returned vector anyway. cheers, Martin

so I would just leave the move and do a `return v;` relying on the fact that even my C++03 my compiler will do RVO and in-place construction of the returned vector anyway.
a year ago I check carefully what gcc would do by inspecting the assembler code generated and indeed it does in-place construction. I since then carelessly always return objects by copy, and when I convert portion of the code that was returning by ref to return by copy I usually do not observe any performance slow-down (although I must say do not always check). Nil

Hi Martin, On 29 August 2011 13:15, Martin B. <0xCDCDCDCD@gmx.at> wrote:
On 26.08.2011 20:21, Ovanes Markarian wrote:
On Fri, Aug 26, 2011 at 2:30 PM, Martin B. <0xCDCDCDCD@gmx.at mailto:0xCDCDCDCD@gmx.at> wrote:
Say I have a range R and I want to construct a new container from the range R. Will I always have to repeat the expression yielding the range, or is there a shorter way?
Example:
std::vector<int> numbers( boost::irange(7, 42).begin(), boost::irange(7, 42).end() );
What about that: ...
integer_range<int> ir=irange(7,42); vector<int> numbers(ir.begin(), ir.end());
For this to work I need the exact type of the range, which can be quite annoying as far as I could tell. (Plus, I *don't want* to care what type of the range is.)
Really, if I had C++11/auto, I wouldn't mind so much, i.e.
auto xr = get_some_range(...); vector<int> numbers(xr.begin(), xr.end());
but I don't have an `auto` capable compiler, so spelling out the range type for this is really crappy.
If you don't care about the type of range, you could always try: BOOST_AUTO( xr, get_some_range(...) ); vector<int> numbers( xr.begin(), xr.end() ); http://www.boost.org/doc/libs/1_47_0/doc/html/typeof/refe.html#typeof.auto Cheers, Darren

On 2011-08-26 12:30:42 +0000, Martin B. said:
Hi!
Say I have a range R and I want to construct a new container from the range R. Will I always have to repeat the expression yielding the range, or is there a shorter way?
This is an interesting topic.
There is *almost* a way to do what you want, using boost assign
list_of, as per the example below. Note that I am assuming that you
want to do this efficiently, hence use the slightly less convenient
(because of the size parameter) cref_list_of function.
There are two main problems with this approach.
1. The initial element of the range has to be explictly provided to
cref_list_of. This is the 0 element in the examples below.
2. The range() function for cref_list_of completely fails when using a
boost::irange. With the exception of the initial value, the container
is filled with the final value of the irange (5 in this example). This
looks like a bug to me…
It would be really good to get boost assign enhanced to remove these
limitations. In fact I wonder if it would be particularly hard to
implement an assign::range_of function which uses the same underlying
mechanism (ie an object which is convertible to the requisite container
type).
#define BOOST_TEST_MODULE assignrange
#include

Den 26-08-2011 14:30, Martin B. skrev:
Hi!
Say I have a range R and I want to construct a new container from the range R. Will I always have to repeat the expression yielding the range, or is there a shorter way?
Example:
std::vector<int> numbers( boost::irange(7, 42).begin(), boost::irange(7, 42).end() );
Note that it's just an example.
Is it possible to create a container C from a range expression R in one step? Any helper function for this?
std::vector<int> numbers =
boost::copy_range
participants (7)
-
Alastair Rankine
-
Darren Garvey
-
Martin B.
-
Nil Geisweiller
-
Ovanes Markarian
-
Szymon Gatner
-
Thorsten Ottosen