Boost logo

Boost Users :

Subject: Re: [Boost-users] More on my result_type problem
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2011-07-19 03:55:41


> I see from the source code that the transform range is calling
> make_transform_iterator which takes two arguments, and that
>
> "If Reference is use_default then the reference member of
> transform_iterator is
> result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type."
>
> The documentation for result_of explains the need, and shows how to use
> a result template instead of a result_type simple type in this case.
> My code follow from the example:
>
> struct ASCII_lower
> {
> // tell details to result_of template, since VS8 doesn't support
> decltype keyword.
> template <typename> struct result;
> template<typename F, typename T>
> struct result<F(T)> { typedef T type; };
>
> template< typename CharT >
> CharT operator() (const CharT& ch) const
> {
> if (ch >= 'A' && ch <= 'Z') return ch+0x20;
> return ch; // unchanged
> }
> };
>
> But, I still get an error that result_type is not found!
>
> B:\boost/iterator/transform_iterator.hpp(42) : error C2039:
> 'result_type' : is not a member of 'vst::internal::ASCII_lower'
> B:\boost/mpl/eval_if.hpp(41) : see reference to class template
> instantiation 'boost::detail::function_object_result<UnaryFunc>' being
> compiled
> with
> [
> UnaryFunc=vst::internal::ASCII_lower
> ]
> B:\boost/iterator/iterator_adaptor.hpp(172) : see reference to
> class template instantiation 'boost::mpl::eval_if<C,F1,F2>' being
> compiled
> with
> [
> C=boost::is_same<boost::use_default,boost::use_default>,
>
> F1=boost::detail::function_object_result<vst::internal::ASCII_lower>,
> F2=boost::mpl::identity<boost::use_default>
> ]
>
>
> It appears to be using function_object_result, not result_of as
> documented. And that is:
> template <class UnaryFunc>
> struct function_object_result
> {
> typedef typename UnaryFunc::result_type type;
> };
> which simply turns result_type into type to make eval_if happy, and
> doesn't do anything fancier.
>
> So, it doesn't work as documented, and neither provides another way of
> passing the parameter in (exposing more arguments from the underlying
> transform_iterator). Is that a bug, or what?

What version of boost are you using?
 
The following code compiles fine for me with 1.47. I know some of
the result_of support has been added recently, so it's possible
you're using an older version that does not contain these fixes.
 
#include <boost/range/begin.hpp>
#include <boost/range/adaptor/transformed.hpp>
struct ASCII_lower
{
    // tell details to result_of template, since VS8 doesn't support decltype keyword.
    template <typename > struct result;
    template <typename F, typename T>
    struct result<F(T)>
    {
        typedef T type;
    };
    template <typename CharT>
    CharT operator()(const CharT& ch) const
    {
        if (ch >= 'A' && ch <= 'Z')
            return ch + 0x20;
        return ch; // unchanged
    }
};
int main()
{
    const char s[] = "HELLO";
    assert('h' == *boost::begin(s | boost::adaptors::transformed(ASCII_lower())));
    return 0;
}
 
Regards,
Nate.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net