$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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