Make safe_iterator inline friends

François Dumont frs.dumont@gmail.com
Thu Aug 23 20:59:00 GMT 2018


On 22/08/2018 23:45, Jonathan Wakely wrote:
> On 22/08/18 23:08 +0200, François Dumont wrote:
>> Only operator== and != remains outside _Safe_iterator because all my 
>> attempts to make them inline friends failed. I understand that an 
>> inline friend within a base class is not a very clean design.
>>
>> Compiler error was:
>>
>> /home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h:459: 
>> error: redefinition of 'bool __gnu_debug::operator==(const _Self&, 
>> const _OtherSelf&)'
>> /home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h:452: 
>> note: 'bool __gnu_debug::operator==(const _Self&, const _Self&)' 
>> previously declared here
>> /home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h:473: 
>> error: redefinition of 'bool __gnu_debug::operator!=(const _Self&, 
>> const _OtherSelf&)'
>> /home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h:466: 
>> note: 'bool __gnu_debug::operator!=(const _Self&, const _Self&)' 
>> previously declared here
>>
>> I don't know if it is a compiler issue
>
> I don't think so. The error seems clear: when _Self and _OtherSelf are
> the same type the friend declarations are the same function.
>
>
_Self and _OtherSelf and like the types defined in _Safe_iterator<_It, 
_Sq, random_access_interator_tag> in this patch. Depending on 
__conditional_type so definitely different.

In _Safe_iterator representing the container iterator type we have 
friend operators:

operator==(iterator, iterator);

operator==(iterator, const_iterator);

And in the one representing const_iterator:

operator==(const_iterator, const_iterator);

operator==(const_iterator, iterator);

but gcc do not see it this way.

I try again without the _Self and _OtherSelf types, using directly 
_Safe_iterator as it should and got:

/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h: 
In instantiation of 'class 
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const 
std::__cxx11::basic_string<char>*, 
std::__cxx1998::vector<std::__cxx11::basic_string<char>, 
std::allocator<std::__cxx11::basic_string<char> > > >, 
std::__debug::vector<std::__cxx11::basic_string<char> >, 
std::forward_iterator_tag>':
/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h:489: 
required from 'class 
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const 
std::__cxx11::basic_string<char>*, 
std::__cxx1998::vector<std::__cxx11::basic_string<char>, 
std::allocator<std::__cxx11::basic_string<char> > > >, 
std::__debug::vector<std::__cxx11::basic_string<char> >, 
std::bidirectional_iterator_tag>'
/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h:631: 
required from 'class 
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const 
std::__cxx11::basic_string<char>*, 
std::__cxx1998::vector<std::__cxx11::basic_string<char>, 
std::allocator<std::__cxx11::basic_string<char> > > >, 
std::__debug::vector<std::__cxx11::basic_string<char> >, 
std::random_access_iterator_tag>'
/home/fdt/dev/gcc/git/libstdc++-v3/testsuite/util/testsuite_abi.cc:419: 
required from here
/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h:449: 
error: redefinition of 'template<class _IteL, class _IteR, class _Seq, 
class _Cat> bool __gnu_debug::operator==(const 
__gnu_debug::_Safe_iterator<_IteL, _Seq, _Cat>&, const 
__gnu_debug::_Safe_iterator<_IteR, _Seq, _Cat>&)'
/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h:449: 
note: 'template<class _IteL, class _IteR, class _Seq, class _Cat> bool 
__gnu_debug::operator==(const __gnu_debug::_Safe_iterator<_IteL, _Seq, 
_Cat>&, const __gnu_debug::_Safe_iterator<_IteR, _Seq, _Cat>&)' 
previously declared here

redefinition and previous declaration are targetting the exact same 
line. This is why I think it has something to do with the inheritance 
between the different iterator types.

But as I said it doesn't really matter for the patch. We can go with 
those 2 operators not inline friends.

So appart from that is it ok to commit ?

François



More information about the Libstdc++ mailing list