
------------------------------
Message: 5 Date: Tue, 07 Jun 2011 09:25:51 -0500 From: "John M. Dlugosz" <mpbecey7gu@snkmail.com> To: boost-users@lists.boost.org Subject: Re: [Boost-users] Ranges to Collections Message-ID: <31696-1307456755-210504@sneakemail.com> Content-Type: text/plain; charset=GB2312
On 6/6/2011 9:31 PM, ??? qiaozhiqiang-at-leadcoretech.com wrote:
Maybe you want make_vector() , make_list().
template<class T, class SinglePassRange> T make_container(const SinglePassRange& from) { T c; boost::push_back(c, from); return move(c); }
I think it would be better to make use of the two-iterator form of the constructor rather than calling push_back. That way it can allocate storage for all elements in advance if the kind of range allows for finding the difference easily.
{ return T (from.begin(), from.end()); }
I guess your way optimizes for the case where it needs to slowly traverse the range in order to find the end() first. I suppose boost::push_back does something similar if it can, but it still constructs as zero size and then resizes.
////////////////////////////////////////////////////// std::vector<T> a; // this line does not allocate storage a.insert(a.end(),boost::begin(from) ,boost::end(from));// boost::push_back(c, from) call insert, this will allocate storage only once if it can. std::vector(begin, end) does not know any range, But boost known more range detail, so you should use boost, and boost should has this function. And you should not call from.begin(), from.end(), you should call boost::begin(from), boost::end(from)
template<class SinglePassRange> std::vector<typename SinglePassRange::value_type> make_vector(const SinglePassRange& from) { return make_container<std::vector<typename SinglePassRange::value_type>>(from); }
The make_container needs to be told the exact container type in the call, and your make_vector et al. is a different name for each possible container. I would think you could use a template template argument and pass in the container species only, and have it obtain the value_type for itself. I think that would be good enough, as the details of the value types is the hard part.
But, I speculate that a simple expression could figure out the complete type by itself via using a templatized conversion operator.
////////////////////////////////////////////////////////// auto v = make_vector(a_range); make_vector() is good friend of AUTO, but templatized conversion operator not. So we need both.