Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clang vs gcc std::crbegin with boost::iterator_range

Clang 3.8.1 with libc++ compiles the following program:

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

#include <boost/range/iterator_range.hpp>

int main()
{
    const std::vector<int> v {1, 2, 3};

    const auto range = boost::make_iterator_range(v);

    std::copy(std::crbegin(range), std::crend(range), std::ostream_iterator<int> {std::cout, " "});
    std::cout << std::endl;

    return 0;
}

But gcc 6.1.0 with libstdc++ does not. First line of gcc error is:

error: no matching function for call to 'crbegin(const boost::iterator_range<__gnu_cxx::__normal_iterator<const int*, std::vector<int> > >&

Who is right?

Note: Boost version 1.61

like image 944
Daniel Avatar asked Aug 10 '16 16:08

Daniel


1 Answers

It's a bug in libc++; std::crbegin is delegating to rbegin, but by calling it unqualified it's picking up boost::rbegin (documentation):

template <class _Cp>
inline _LIBCPP_INLINE_VISIBILITY
auto crbegin(const _Cp& __c) -> decltype(rbegin(__c))
{
    return rbegin(__c);
    //     ^-- unqualified, allows ADL
}

This is contrary to [iterator.range], which says that crbegin should delegate to std::rbegin only:

template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));

14 - Returns: std::rbegin(c).

Libc++'s implementations of cbegin, cend and crend have the same bug.

like image 149
ecatmur Avatar answered Oct 05 '22 23:10

ecatmur