metamorphosis February 2016

MSVC compiler bug causing error with iterators and friend functions?

I've been working on a small-scale test to see if I can figure out some compiler-specific larger-scale problems with a larger container. The following code works fine in GCC but causes the following error code in Visual Studio 2010 and 2013:

"Error 1 error C2675: unary '--' : 'std::iterator' does not define this operator or a conversion to a type acceptable to the predefined operator d:\programming\workspaces\adl_test\main.cpp 127 1 adL_test_msvc"

Test code is as follows:

#include <iostream>
#include <iterator>

namespace nsp
{

template <class element_type, class element_allocator_type = std::allocator<element_type> >
class test_container
{
private:
    element_type numbers[50];
    friend class iterator;
    friend class reverse_iterator;

public:
    class reverse_iterator; //forward decl

    class iterator : public std::iterator<std::bidirectional_iterator_tag, element_type>
    {
    private: 
        element_type *i;

        template <class distance_type>
        friend void advance(reverse_iterator &rit, distance_type n);
    public: 

        iterator() {}

        iterator(element_type &_i)
        {
            i = &(_i);
        }

        element_type & operator *()
        {
            return *i;
        }

        iterator & operator = (const element_type &source_i)
        {
            i = &(source_i);
            return *this;
        }

        iterator & operator = (const iterator &source)
        {
            i = source.i;
            return *this;
        }

        bool operator != (const iterator rh)
        {
            return i != rh.i;
        }

        iterator & operator ++()
        {
            ++i;
            return *this;
        }

        iterator & operator --()
        {
            --i;
            return *this;
        }



        template <class distance_type>
        friend void advance(iterato        

Answers


metamorphosis February 2016

Thanks to immibus, the answer has been found: GCC believes 'iterator' within reverse_iterator refers to test_container::iterator, whereas (for some reason) MSVC 2010-2013 believes it refers to the base class. The solution is to be more specific when specifying iterator within reverse_iterator - using "typename test_container::iterator" instead of "iterator".

Corrected code:

#include <iostream>
#include <iterator>

namespace nsp
{

template <class element_type, class element_allocator_type = std::allocator<element_type> >
class test_container
{
private:
    element_type numbers[50];
    friend class iterator;
    friend class reverse_iterator;

public:
    class reverse_iterator; //forward decl

    class iterator : public std::iterator<std::bidirectional_iterator_tag, element_type>
    {
    private: 
        element_type *i;

        template <class distance_type>
        friend void advance(reverse_iterator &rit, distance_type n);
    public: 

        iterator() {}

        iterator(element_type &_i)
        {
            i = &(_i);
        }

        element_type & operator *()
        {
            return *i;
        }

        iterator & operator = (const element_type &source_i)
        {
            i = &(source_i);
            return *this;
        }

        iterator & operator = (const iterator &source)
        {
            i = source.i;
            return *this;
        }

        bool operator != (const iterator rh)
        {
            return i != rh.i;
        }

        iterator & operator ++()
        {
            ++i;
            return *this;
        }

        iterator & operator --()
        {
            --i;
            return *this;
        }



        template <class distance_type>
        friend void advance(iterator &it, distance_type n)
        {
            it.i += n;
        }

        friend typename std::iterator_tra 

Post Status

Asked in February 2016
Viewed 2,342 times
Voted 6
Answered 1 times

Search




Leave an answer