On Mon, May 10, 2010 at 2:35 AM, Denis Taniguchi <taniguchi@tpn.usp.br> wrote:
Hi,

I was trying to compile the following simple piece of code:

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>

#include <vector>

int main(int argc, char *argv[])
{
 std::vector<int> vec(10);
 boost::fill(vec | boost::adaptors::reversed, 1);

 return 0;
}

But I get the following erros with gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3:
Am I missing something here?


The reason this will not compile is that 'vec | boost::adaptors::reversed' returns an unnamed temporary which is then attempted to be passed to the fill function. On many versions of Visual C++ this actually will compile and work as you intended due to a language extension, but this is non-standard.

This can't easily be remedied since the Range Concept is non-copyable, and we obviously can't pass a const reference as the target to the fill algorithm. Making the Range Concept cheaply copyable would mean that the standard containers were no longer a model of the Range Concepts. I am currently investigating extending the sub_range into some new Range concepts that would integrate Alexandrescu's work into Boost.Range nicely. These sub-ranges would have to be copyable with constant-time complexity and therefore would enable the fill function to be written to take the sub-range by value. This would make your code compile. This work, however is very much in the experimental stage.

However this isn't a big problem because we typically solve the problem with the current Boost.Range like this:

#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/irange.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <vector>

int main(int argc, char *argv[])
{
std::vector<int> vec;
boost::push_back(vec, boost::irange(0, 10) | boost::adaptors::reversed);
return 0;
}

The adaptor is more typically applied to the right-hand side of the expression, and the population of a target container is normally better achieved by using one the algorithm_ext functions. In this case I am demonstrating the use of push_back.

This is better arrangement over the example code because the size does not have to be ascertained twice (once in the constructor of vec, and again in the actual source expression).

The other alternative arrangements that are equally safe to the new push_back use an back_insert_iterator which is less efficient.

Hence the new algorithms for transferring ranges to containers are safer, cleaner and more efficient than the alternative designs.
 
Best regards,

Denis


Regards,
Neil Groves