tags:

views:

113

answers:

1

Please don't mind that there is no insert fnc and that data are hardcoded. The main purpouse of it is to correctly implement iterator for this container.

//file Set.h
#pragma once

template<class T>
class Set
{
    template<class T>
    friend ostream& operator<<(ostream& out, const Set<T>& obj);
private:
    T** myData_;
    std::size_t mySize_;
    std::size_t myIndex_;
public:

    Set();
    class iterator : public std::iterator<std::random_access_iterator_tag, T*>
    {
    private:

        T** itData_;

    public:

        iterator(T** obj)
        {
            itData_ = obj;

        }

        T operator*() const
        {
            return **itData_;
        }
        /*Comparing values of two iterators*/
        bool operator<(const iterator& obj)
        {
            return **itData_ < **obj.itData_;
        }

        /*Substracting two iterators*/
        difference_type operator-(const iterator& obj)
        {
            return itData_ - obj.itData_;
        }

        /*Moving iterator backward for value*/
        iterator operator-(const int value)
        {
            return itData_ - value;
        }

        /*Adding two iterators*/
        difference_type operator+(const iterator& obj)
        {
            return itData_ + obj.itData_;
        }

        /*Moving iterator forward for value*/
        iterator operator+(const int value)
        {
            return itData_ + value;
        }

        bool operator!=(const iterator& obj)
        {
            return (itData_ != obj.itData_);
        }

        bool operator==(const iterator& obj)
        {
            return (itData_ == obj.itData_);
        }

        T** operator++()
        {
            return ++itData_;
        }

        T** operator--()
        {
            return --itData_;
        }
    };

    iterator begin() const
    {
        return myData_;
    }

    iterator end() const
    {
        return myData_ + myIndex_;
    }
};

template<class T>
ostream& operator<<(ostream& out, const Set<T>& obj)
{
    for (int i = 0;i < 3; ++i)
    {
        out << *obj.myData_[i] << "\n";
    }
    return out;
}

//file Set_impl.h
#pragma once
#include "stdafx.h"
#include "Set.h"

template<class T>
Set<T>::Set()
{
    mySize_ = 3;
    myIndex_ = 3;
    myData_ = new T*[mySize_];
    myData_[0] = new T(3);
    myData_[1] = new T(1);
    myData_[2] = new T(2);
}

//main
include "stdafx.h"
#include "Set_impl.h"

int _tmain(int argc, _TCHAR* argv[])
{
    Set<int> a;
    Set<int>::iterator beg_ = a.begin();
    Set<int>::iterator end_ = a.end();
    std::sort(beg_,end_);//WONT SORT THIS RANGE
    cin.get();
    return 0;
}

Why sort can't accept this iterators even though I've provided all operators needed for sort to work? I think the best way to check what's going on is to paste this code and run it first. Thanks

+7  A: 

Your code is unfortunately a complete mess.

What prohibits it from compiling is probably the following:

class iterator : public std::iterator<std::random_access_iterator_tag, T*>

This says that when you perform *iterator, it yields a T*. But look at what operator* actually returns:

T operator*() const

I can make it compile by changing those to:

class iterator : public std::iterator<std::random_access_iterator_tag, T>

and

T& operator*() const

(in addition to numerous other changes since GCC doesn't seem to like this a lot)


    /*Comparing values of two iterators*/
    bool operator<(const iterator& obj)
    {
        return **itData_ < **obj.itData_;
    }

This is also wrong. It should be related to operators == and !=, that is, it shouldn't be comparing the values, but the iterators. (Luckily for you I doubt, std::sort actually ever uses this method.)

    T** operator++()
    {
        return ++itData_;
    }

    T** operator--()
    {
        return --itData_;
    }

These should return a reference to the iterator itself (again, the return value is most probably not used by the library).

UncleBens
@Uncle but T** operator++ and operator-- they do return reference to themself.
There is nothing we can do
That would be: `iterator return *this; }`
UncleBens
@Uncle but the result is the same only without conversions so I'm not sure if it actually better to specify the way you've suggested but of course I'm just asking not arguing.
There is nothing we can do
No, there will be implicit conversions the way you do it. Consider usage: `iterator a, b; a = ++b;` If `++` returns a `T**`, then it must first be implicitly converted back to `iterator` before it can be assigned to `a`. (And in addition, in the middle you leak internal implementation details to the outside world.)
UncleBens
@Uncle and even though I've did changes you've suggested it still won't compile.
There is nothing we can do
@Uncle I gave you +1 for your last comment. Point taken. But still it won't compile.
There is nothing we can do
Too bad, then. I can easily get it to compile and have it output 1, 2, 3. - I'm afraid it takes a psychic to know what might be wrong now. Perhaps ask another question? (SO is a bit bad for iteratively fixing coding errors, a forum such as http://cboard.cprogramming.com/cplusplus-programming/ might be more suitable.)
UncleBens
@Uncle Thanks for your advice.
There is nothing we can do