http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58191

--- Comment #5 from Daniel Krügler <daniel.kruegler at googlemail dot com> ---
(In reply to Paolo Carlini from comment #2)
> Francois, did we change anything in the library for 4.8.x?

I think that Francois added more iterator concept checking and this one looks
correct. Unfortunately I would say, this is correct, because the standard says
so, but from a practical point of view, std::upper_bound "just works" for any
forward traversal iterator and it does not require that the return type of
operator* *really* is a reference type. We also cannot blame boost here,
because it is not their fault that the standard requires for forward iterators
to have a real reference return type for iterator dereference. My
recommendation to the issue reporter would be to provide a function object that
returns a real reference. This can be easily done by a unary functor adaptor
such as the following one:

template<class UnaryFunction, class ArgumentType>
struct LValueUnaryFunctionAdaptor
{
  typedef typename std::result_of<const UnaryFunction(ArgumentType)>::type
value_type;
  LValueUnaryFunctionAdaptor(UnaryFunction func) : func(func) {}
  typedef const value_type& result_type;
  result_type operator()(ArgumentType arg) const
  {
    return res = func(arg);
  }
private:
  UnaryFunction func;
  mutable value_type res;
};

template<class ArgumentType, class UnaryFunction>
inline
LValueUnaryFunctionAdaptor<UnaryFunction, ArgumentType>
make_LValueUnaryFunction(UnaryFunction func)
{
  return LValueUnaryFunctionAdaptor<UnaryFunction, ArgumentType>(func);
}

So instead of

calc_value

he could use

make_LValueUnaryFunction<int>(calc_value)

This trick doesn't make the transform_iterator fully conforming, but it should
convince the compile-time test machinery.

Reply via email to