https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68222

            Bug ID: 68222
           Summary: _Safe_iterator provides operators the wrapped iterator
                    can't actually support
           Product: gcc
           Version: 5.2.1
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: TonyELewis at hotmail dot com
  Target Milestone: ---

It would be very helpful if the _Safe_iterator wrapper disabled operators, such
as non-member operator-(), that aren't actually supported by the wrapped
iterator type. Since the non-member operator-() is well formed, modern iterator
 code might reasonably choose to enable code that uses it but this will result
in a compile error. One example of this cropping up:

https://github.com/ericniebler/range-v3/issues/231

This issue is illustrated in the following code:

// Turn debug mode on
#define _GLIBCXX_DEBUG

#include <iostream>
#include <list>

template <typename... Ts> void ignore_unused(const Ts &...);

int main() {
        // A list of int
        const std::list<int> nums = { 1, 2, 3, 4 };

        // Grab the iterator type (which is
_Safe_iterator<_List_const_iterator<int>, list<int> >)
        using list_itr_type = decltype( std::cbegin( nums ) );
        // TD<list_itr_type> bob;

        // Confirm cend returns the same type
        static_assert( std::is_same< decltype( std::cend( nums ) ),
list_itr_type >::value, "" );

        // The list's iterator type provides a well-formed non-member
operator-() with valid return type (long int)
        using subtraction_return_type = decltype( std::declval<list_itr_type>()
- std::declval<list_itr_type>() );
        static_assert( std::is_same< subtraction_return_type, long int
>::value, "" );

        // Yet an attempt to actually fails to compile because the wrapped list
iterator
        // doesn't support operator-()
        const auto fail_here = std::cend( nums ) - std::begin( nums );
        ignore_unused( fail_here );

        return 0;
}


// Command : g++ -std=c++14 -Wall -Wextra -fno-strict-aliasing -fwrapv
-fno-aggressive-loop-optimizations safe_itr_prob.cpp
// STL     : GNU libstdc++ version 20151010 (
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21 )
// Compiler: GNU C++ version 5.2.1 20151010
// OS      : Ubuntu 15.10 (Linux 4.2.0-16-generic #19-Ubuntu SMP Thu Oct 8
15:35:06 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux)

Reply via email to