Boost logo

Boost Users :

Subject: [Boost-users] [signals] What's special about iterators passed to combiners?
From: Boris Schaeling (boris_at_[hidden])
Date: 2010-05-14 09:13:16


A reader of my book noticed that the sample program at
http://en.highscore.de/cpp/boost/src/4.2.8/main.cpp which uses a combiner
to return the smallest value of all slot values is buggy. The combiner's
implementation is rather simple as iterators are simply forwarded to
std::min_element():

template <typename T>
struct min_element
{
   typedef T result_type;

   template <typename InputIterator>
   T operator()(InputIterator first, InputIterator last) const
   {
     return *std::min_element(first, last);
   }
};

As simple as the implementation is: This combiner does not return the
smallest value but always the value the first iterator refers to (at least
with VC++ 2008 and g++ 4.2.1). This can be easily tested by swapping the
return values of the two functions func1() and func2() in the sample
program.

First I was trying to find a fix - temporarily copying the values to a
container is all what is needed:

T operator()(InputIterator first, InputIterator last) const
{
   std::vector<T> v(first, last);
   return *std::min_element(v.begin(), v.end());
}

Then I was trying to understand what's special about the iterators. Please
look at the following code and guess whether the values printed will be
different or not:

T operator()(InputIterator first, InputIterator last) const
{
   InputIterator temp = first;
   ++first;
   std::cout << *first << std::endl;
   std::cout << *temp << std::endl;
}

If you think you get two different values then you'll be as surprised as I
am: Both iterators temp and first return the second value in the range
[first, last).

I can't find any explanation in the Boost.Signals documentation. I
wouldn't be surprised though if this is a known issue because there is a
sample combiner called maximum used (see
http://www.boost.org/doc/libs/1_43_0/doc/html/signals/tutorial.html#id1730406)
which doesn't use an algorithm from the C++ standard (I guess
intentionally?).

Anyway: Is this a bug? If it isn't is there a recommended work-around
(apart from temporarily copying values to a container)? Then it's probably
not safe to use any C++ standard algorithm in combiners? Could this be
added to the FAQ or anywhere else in the Boost.Signals documentation?

Boris


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