2010-04-23 3 views
1

Пожалуйста, не помните, что нет вставки fnc и данные жестко закодированы. Основная его цель - правильно реализовать итератор для этого контейнера.Почему я не могу сортировать этот контейнер?

//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; 
} 

Почему сортировка не может принимать эти итераторы, даже если я предоставил всем операторам необходимые для сортировки работу? Я думаю, что лучший способ проверить, что происходит, - вставить этот код и запустить его в первую очередь. Спасибо

+0

Не полный ответ, поэтому я оставлю его только как комментарий: оператор итератора * должен возвращать ссылочный тип коллекции, а не значение. В противном случае теперь для sort() можно изменить значения, на которые указывает итератор. –

+0

@ Эрик после изменений вы предположили, что я получаю только одну ошибку: Ошибка ошибка C2440: 'return': невозможно преобразовать из 'double' в 'double &' \t Любая идея, почему? –

ответ

7

Ваш код, к сожалению, полный беспорядок.

Что запрещает его от компиляции, вероятно, следующее:

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

Это говорит о том, что при выполнении *iterator, он дает T*. Но посмотрите на то, что operator* фактически возвращает:

T operator*() const 

я могу сделать его компиляции путем изменения тех:

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

и

T& operator*() const 

(в дополнение к многочисленным другим изменениям, так как GCC Безразлично 't, кажется, нравится это много)


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

Это также неправильно. Он должен быть связан с operators == и !=, то есть не следует сравнивать значения, но итераторы. (К счастью для вас, я сомневаюсь, std::sort на самом деле когда-нибудь использует этот метод.)

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

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

Они должны возвращать ссылку на сам итератор (опять же, возвращаемое значение, скорее всего, не используется библиотекой).

+0

@Uncle, но T ** оператор ++ и оператор - они возвращают ссылку на себя. –

+0

Это будет: 'iterator & operator ++() {++ itData_; return * this; } ' – UncleBens

+0

@Uncle, но результат тот же, что и без конверсий, поэтому я не уверен, действительно ли лучше указать способ, который вы предложили, но, конечно, я просто прошу не спорить. –

Смежные вопросы