Hi Hurcan,

2013/1/16 Hurcan Solter <hsolter@gmail.com>

The following snippet is the mock-up of the problem I am having in order to be able to reproduce.

--------------------------------------------------------------------------------
#include <iostream>
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/bind.hpp>
#include <boost/assign.hpp>


using namespace boost::assign;
struct wxSize
{
    wxSize(int height=0,int width=0):m_height(height),m_width(width)
    { }
    int GetWidth() const {return m_width;}
    int m_height;
    int m_width;
};
class wxWindowBase
{
public:
    wxSize GetTextExtent(const std::string val)
    {
        return wxSize(0,val.length());
    }
    void DoLayout(std::vector<std::string> m_FilteredItems)
    {

        using boost::adaptors::transformed;
        wxSize longest = *boost::max_element(m_FilteredItems | transformed(boost::bind(&wxWindowBase::GetTextExtent,this,_1)),
                                   boost::bind(std::less<int>(),boost::bind(&wxSize::GetWidth,_1),boost::bind(&wxSize::GetWidth,_2)));

        std::cout <<longest.GetWidth();
    }
};
int main()
{
    std::vector<std::string> input;
    input += "o","two","threexxx","four";
    wxWindowBase window;
    window.DoLayout(input);
}
-----------------------------------------------------------------------------------------
The above code fails to compile on GCC4.7.2 and MSVC10 although
it compiles and runs fine on clang3.3

From what I understand ,transformed returns a Single Pass Range and max_element expects a ForwardRange
and that's the gist of the problem.But it works for something like
 
         max_element(someint_vector | transformed(doubleit()),std::less<int>()); without problems.

Is there a elegant way to achieve what I am trying to without using a intermediate container?
Thanks in advance..

This problem's some solution:

1. Don't use member function version `bind` in `transformed`.
the `bind`'s result functor is not DefaultConstructible.
An iterator holding such a functor can't conform to even Input Iterator. (`max_element` need default construct operation for iterator.)

2. Use `regular` function.
`regular` function is Boost.Range extension library's feature.
`regular` function is convert functor to DefaultConstructible and CopyAssignable.

http://dl.dropbox.com/u/1682460/git/OvenToBoost/libs/range/doc/html/range_extension/reference/range_utilities/regular.html
http://dl.dropbox.com/u/1682460/git/OvenToBoost/libs/range/doc/html/range_extension/reference/regular_extension/transformed.html

#include <boost/range/adaptor/regular_extension/transformed.hpp>

wxSize longest = *boost::max_element(m_FilteredItems |+ transformed(boost::bind(&wxWindowBase::GetTextExtent,this,_1)),
                                   boost::bind(std::less<int>(),boost::bind(&wxSize::GetWidth,_1),boost::bind(&wxSize::GetWidth,_2)));

You can get here:
https://github.com/faithandbrave/OvenToBoost

This extension is now reviewing by Boost.Range developers.

Thanks,
Akira

>>========================
Akira Takahashi
mailto:faithandbrave@gmail.com
https://sites.google.com/site/faithandbrave/about/en