0

I am working with c++11.I am have working on my custom iterator and i want to test it on std::sort function. Here is my code. i have tried to use (const &) a lot. It seems it didn't work.

main:

    PFArray<int> obj;
    obj.add(7);
    obj.add(1);
    obj.add(2);
    obj.add(3);
    obj.add(5);
    iterator_y<int> c;
    c =obj.begin();
    sort(obj.begin(),obj.end());
    for(c = obj.begin();c != obj.end();c++)
    {
        cout << *(c);
    }

PFArray.hpp:

class PFArray
{
    public:
        PFArray();
        void read_sptr();
        int size();
        bool empty();
        void add(const T& eleman);
        iterator_y<T> begin();
        iterator_y<T> end();
        const iterator_y<T> cbegin()const;
        void clear();

    private:
        shared_ptr<T> m_ptr;
        int size_eleman=0;
};

template<class T>
PFArray<T>::PFArray()
{
    m_ptr = nullptr;
    size_eleman = 0;
    cout << "constructer done"<<endl;
}
template<class T>
void PFArray<T>::read_sptr()
{
    size_eleman =5;
    cout << "BB"<<endl;

}
template<class T>
iterator_y<T> PFArray<T>::begin()
{
    return iterator_y<T>(m_ptr);
}
template<class T>
int PFArray<T>::size()
{
    return size_eleman;
}
template<class T>
bool PFArray<T>::empty()
{
    if(m_ptr ==nullptr)
        return true;
    return false;
}
template<class T>
iterator_y<T> PFArray<T>::end()
{
    return iterator_y<T>(m_ptr) + size_eleman ;
}
template<class T>
void PFArray<T>::add(const T& eleman)
{
    auto it = this->begin();
    //m_ptr = shared_ptr<T>(new T [size_eleman+1]);
    //shared_ptr<T> temp = make_shared<T>(size_eleman+1);
    shared_ptr<T> temp =shared_ptr<T>(new T [size_eleman+1]);
    iterator_y<T> it2(temp);
    for(;it != this->end();++it,++it2)
    {
        *(it2) = *(it);
    }
    *(it2) = eleman;
    ++size_eleman;
    m_ptr = temp;
}
template<class T>
const iterator_y<T> PFArray<T>::cbegin()const
{
    const iterator_y<T> temp(m_ptr);
    return temp;
}
template<class T>
void PFArray<T>::clear()
{
    shared_ptr<T> obj;
    m_ptr = obj;
    size_eleman=0;
}

and here is the my_iter.cpp:

class iterator_y
{
    public:
        iterator_y();
        iterator_y(const iterator_y<T> & obj);
        iterator_y(const shared_ptr<T>& x_ptr);
        /*----------------------------------------------------------------------*/
        iterator_y<T> operator + (const int & size_element);
        iterator_y<T> operator - (const int & num);
        iterator_y<T> operator++();
        iterator_y<T> operator++(int); 
        iterator_y<T> operator--();
        iterator_y<T> operator--(int);
        bool operator<(const iterator_y<T>& obj);
        iterator_y<T> operator+=(int num);
        iterator_y<T> operator-=(int num);
        /*----------------------------------------------------------------------*/
        bool operator<=(const iterator_y<T>&obj)const;
        bool operator<(const iterator_y<T>&obj)const;
        bool operator>(const iterator_y<T>&obj)const;
        bool operator>=(const iterator_y<T>&obj)const;
        int operator-(const iterator_y<T>&);
        template <class Y> friend iterator_y<Y> operator+(int, const iterator_y<Y>&);
        /*************************************************************************/
        void operator=(const iterator_y<T>&& obj);
        void operator=(const iterator_y<T>& obj);
        bool operator != (const iterator_y<T>& diff);
        bool operator == (const iterator_y<T>& diff);
        /***********************************************/
        T& operator*();
        T& operator[](const int &);
        using   value_type = T;
        using   pointer = T*;
        using   reference = T&;
        using   difference_type = int;
        using   iterator_category = random_access_iterator_tag;
    private:
        T* ptr;
};

template<class T>
iterator_y<T>::iterator_y()
{
    ptr=nullptr;
}
template<class T>
iterator_y<T>::iterator_y(const shared_ptr<T>& x_ptr)
{
    ptr= x_ptr.get();
}
template<class T>
iterator_y<T> iterator_y<T>::operator+(const int& size_element)
{


    iterator_y<T> temp= *this;
    temp.ptr = this->ptr;
    temp.ptr +=size_element;
    return temp;
}
template<class T>
iterator_y<T> iterator_y<T>::operator++()
{
    ++ptr;
    return *(this);
}
template<class T>
bool iterator_y<T>::operator!=(const iterator_y<T>& diff)
{
    if(ptr != diff.ptr)
        return true;
    return false;
}
template<class T>
T& iterator_y<T>::operator*()
{
    return *(ptr);
}

template<class T>
bool iterator_y<T>::operator==(const iterator_y<T> &diff)
{
    if(ptr ==diff.ptr)
        return true;
    return false;
}

template<class T>
iterator_y<T> iterator_y<T>::operator--()
{
    ptr--;
    return (*this);
}
template<class T>
iterator_y<T> iterator_y<T>::operator++(int)
{
    iterator_y<T> temp = *this;
    ptr++;
    return temp;
}
template<class T>
iterator_y<T> iterator_y<T>::operator--(int)
{
    iterator_y<T> temp = *this;
    ptr--;
    return temp;
}
template<class T>
void iterator_y<T>::operator=(const iterator_y<T>& obj)
{
    ptr = obj.ptr;
}
template<class T>
void iterator_y<T>::operator=(const iterator_y<T>&& obj)
{
    ptr = obj.ptr;
    
}
template<class T>
iterator_y<T>::iterator_y(const iterator_y<T> & obj)
{
    ptr = obj.ptr;
}
template<class T>
iterator_y<T> iterator_y<T>::operator+=(int num)
{
    ptr += num;
    return *(this);
}
template<class T>
iterator_y<T> iterator_y<T>::operator-=(int num)
{
    ptr -=num;
    return *(this);
}
template<class T>
bool iterator_y<T>::operator<(const iterator_y<T>& obj)const
{
    T* temp =obj.ptr;
    if(*ptr<*temp)
        return true;
    return false;
}
template<class T>
bool iterator_y<T>::operator<=(const iterator_y<T>&obj) const
{
    T* temp = obj.ptr;
    if(*ptr<=*temp)
        return true;
    return false;
}
template<class T>
bool iterator_y<T>::operator>(const iterator_y<T>&obj)const
{
    T* temp = obj.ptr;
    if(*ptr>*temp)
        return true;
    return false;
}
template<class T>
bool iterator_y<T>::operator>=(const iterator_y<T>&obj)const
{
    T* temp = obj.ptr;
    if(*ptr>=*temp)
        return true;
    return false;
}
template<class T>
T& iterator_y<T>::operator[](const int &num)
{
    return ptr[num];
}
template<class T>
iterator_y<T> iterator_y<T>::operator-(const int&num)
{
    iterator_y<T> temp= *this;
    temp.ptr = this->ptr;
    temp.ptr -=num;
    return temp;
}
template<class T>
int iterator_y<T>::operator-(const iterator_y<T>& obj)
{
    int count;
    iterator_y<T> temp = *this;
    while(temp.ptr != obj.ptr)
    {
        temp++;
        count;
    }
    return count;
}
template <class Y> 
iterator_y<Y> operator+(const int& num , const iterator_y<Y>& obj)
{
    iterator_y<Y> temp= obj;
    temp.ptr = obj.ptr;
    temp.ptr +=num;
    return temp;
}

this is compiler error.

/usr/bin/ld: main.o: in function `void std::__heap_select<iterator_y<int>, __gnu_cxx::__ops::_Iter_less_iter>(iterator_y<int>, iterator_y<int>, iterator_y<int>, __gnu_cxx::__ops::_Iter_less_iter)':
main.cpp:(.text._ZSt13__heap_selectI10iterator_yIiEN9__gnu_cxx5__ops15_Iter_less_iterEEvT_S5_S5_T0_[_ZSt13__heap_selectI10iterator_yIiEN9__gnu_cxx5__ops15_Iter_less_iterEEvT_S5_S5_T0_]+0x86): undefined reference to `iterator_y<int>::operator<(iterator_y<int> const&)'
/usr/bin/ld: main.o: in function `iterator_y<int> std::__unguarded_partition<iterator_y<int>, __gnu_cxx::__ops::_Iter_less_iter>(iterator_y<int>, iterator_y<int>, iterator_y<int>, __gnu_cxx::__ops::_Iter_less_iter)':
main.cpp:(.text._ZSt21__unguarded_partitionI10iterator_yIiEN9__gnu_cxx5__ops15_Iter_less_iterEET_S5_S5_S5_T0_[_ZSt21__unguarded_partitionI10iterator_yIiEN9__gnu_cxx5__ops15_Iter_less_iterEET_S5_S5_S5_T0_]+0xf9): undefined reference to `iterator_y<int>::operator<(iterator_y<int> const&)'
collect2: error: ld returned 1 exit status
make: *** [makefile:6: main] Error 1

I have tried use move elements and i tried to use (const &) but it seems it doesn't work. Edit: i have changed the code i put the implementations into header files. Nothing has changed.

yukara
  • 18
  • 3
  • First please try to create a [mre] to show us. How do you use the files you show? And then also tell us how you build your application. Please [edit] your question to tell us. – Some programmer dude Jan 05 '23 at 11:29
  • @Caleth That's the wrong duplicate: there's an explicit instanciation at the end of `my_iter.cpp`. It's just missing some of the member implementations. The imho correct duplicate would be https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix – fabian Jan 05 '23 at 11:33
  • Nb: you don't need `iterator_y` *at all*. `T*` is a valid iterator – Caleth Jan 05 '23 at 11:37
  • is T* a valid iterator or is a valid pointer? – yukara Jan 05 '23 at 11:39
  • Better duplicate: [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Richard Critten Jan 05 '23 at 11:40
  • 2
    @yukara All pointers can act as iterators. – Some programmer dude Jan 05 '23 at 11:46
  • This is my homework and i am not allowed to hold my data in regular pointers. I am talking about for "PFArray class". – yukara Jan 05 '23 at 11:52
  • @yukara see the alternative duplicate above - all template code needs to be in header files. – Richard Critten Jan 05 '23 at 11:55
  • I have changed to code but nothing has changed. it still the same – yukara Jan 05 '23 at 12:09
  • _"...and here is the my_iter.cpp:..."_ contains `template iterator_y::iterator_y()...` which is template code in a non-header file. – Richard Critten Jan 05 '23 at 12:15
  • There were two operator< declaration in my_iter.hpp so it was the problem. – yukara Jan 05 '23 at 12:20
  • 2
    By itself that shouldn't be a problem, and should not lead to linker errors. The problem is that you had two *different* `operator<` function overloads, and you only defined (implemented) *one* of them (while the compiler wanted to use the other). – Some programmer dude Jan 05 '23 at 12:41

0 Answers0