Boost logo

Boost Users :

Subject: [Boost-users] don't give template arguments to make_iterator_range
From: Matei David (matei_at_[hidden])
Date: 2014-03-07 18:00:11


Hi,

I recently came across an issue with make_iterator_range(), which is
used to externally construct iterator_range objects. The problem is
that if a template argument is explicitly specified, gcc 4.8.2 refuses
to compile the code. In the meantime, clang 3.4 compiles it without
warnings. This runs contrary to the intuition that specifying a template
argument can only help (speed up) compilation.

You might want to make a note about this in the documentation to Boost
Range: "Don't give an explicit template argument to
make_iterator_range! If you do, the program will be ill-formed!"

The heavily simplified problem is explained here:
http://stackoverflow.com/questions/22258054/c-inconsistency-between-gcc-and-clang

The internal Boost Range details are the following.

As described here:
http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/utilities/iterator_range.html
make_iterator_range has 5 overloads, all of which are template
functions. Consider the 1st and 4th overloads:

template <typename It>
iterator_range<It>
make_iterator_range(It, It);

template <typename R>
iterator_range<typename range_iterator<R>::type>
make_iterator_range(Range&,
  typename range_difference<R>::type,
  typename range_difference<R>::type);

The problem occurs if I write something like:

Some_Iterator it;
auto r = make_iterator_range<Some_Iterator>(it, it);

Specifically, when gcc encounters this call to make_iterator_range, for
a reason I don't fully understand (but others do, see the reply on SO),
it does not eliminate the 2nd overload listed above from consideration,
and instead it tries to instantiate the bogus type range_iterator<R>
with R=Some_Iterator. I say "bogus" because the template argument of
range_iterator is meant to be a range, not an iterator. In turn, this
triggers a compilation error. In the meantime, clang happily eliminates
the 2nd overload, probably based on the fact that it needs 3 arguments,
not 2 as are given in the call.

The problem disappears if I don't give an explicit template argument:

auto r = make_iterator_range(it, it);

even though the correct overload is indeed the first one, with argument
Some_Iterator.

Apparently giving an explicit template argument at that point makes the
program ill-formed. I don't fully understand why, but see the SO
comments.

M


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