简体   繁体   中英

Internal templated class c++

I'm trying this little exercice from my c++ class and i've manage to do this from now.

It's not fully completed, but for now i'm facing the eternal problem of template of internal class.

I've seen a lot of different solution here on stack and on other websites, but still missing someting. + my goal at the end is also to understand the "why".

It's an Iterator internal class needed to iterate to my array. I've seen some exemple giving 2 differents typename for External and Iternal class and then using the typedef, but i'm not sure what's the best way to implement it.

As you can understand my Iterator class need to take the same kind of type as my Array class.

I for sure will need to change some function signatures and add some <\\T> here and there, but for now i just need to avoid all the template traps.

using namespace std;

template <typename T>
class Iterator;

template<typename T>
class Array{

    T* _data;
    size_t _size;
    Iterator* _start;

public:

    class Iterator{
        T* content;

    public:
        explicit Iterator(T* value):content(value){}

        Iterator& operator++(){
            ++content;
            return *this;
        }

        T* operator*(){
            return content;
        }

        bool operator ==(const Iterator& o)const{
            if(content == o.content){
                return true;
            }
            return false;
        }

        bool operator !=(const Iterator& o)const{
            return !(*this == o);
        }
    };


    Array(const size_t s):_size(s){
        _data = new T[_size]();
        _start = new Iterator(_data);
    }

    Array(const Array& o):_size(o._size), _data(o._data), _start(o._start){}

    Array(const std::initializer_list<T>& list):_size(list.size()){
        auto start = list.begin();
        auto fin = list.end();

        _data = new T[_size];

        size_t index = 0;
        while(start != fin){
        _data[index++] = *start++;
        }

        _start = new Iterator(_data);
    }

    virtual ~Array(){
        cout << "~Array" << endl;
        delete[] _data;
    }

    Array<T>& operator= (const Array& o){
        if(this != &o){
            delete[] _data;

            for (size_t i = 0; i < o._size; ++i) {
                _data[i] = o._data[i];
            }
            _size = o._size;
        }

        return *this;
    }

    T& operator[](const size_t index){
        if(index < _size){
            return *_data[index];
        }
    }

    const size_t size()const{
        return _size;
    }

    Iterator begin(){
        return Iterator(_data[0]);
    }

    Iterator end(){
        return Iterator(_data[_size-1]);
    }

};

Can you please give me a clue or help me with this.

For more here is my basic main:

#include "Array.h"

int main() {

    Array<string> array({"h","e","l","l","o"});

    for (Array<string>::Iterator i = array.begin(); i != array.end(); ++i)
        cout << *i << endl;

    return 0;
}

Thank you!

There is no template Iterator at the global scope, so this is wrong:

template <typename T>
class Iterator;

Also, Array<T>::Iterator isn't a template, it's just an inner class. You can simply forward-declare it inside the class like this:

template<typename T>
class Array {
public:
    class Iterator;

Then there are some bugs in your code (eg end() should be 1 past the last element, you need to dereference the iterator twice and construct one from a pointer).

Here's a fixed version:

#include <iostream>
#include <string>

using namespace std;

template<typename T>
class Array {

    T* _data;
    size_t _size;
public:
    class Iterator;
private:
    Iterator* _start;

public:

    class Iterator {
        T* content;

    public:
        explicit Iterator(T* value) :content(value) {}

        Iterator& operator++() {
            ++content;
            return *this;
        }

        T* operator*() {
            return content;
        }

        bool operator ==(const Iterator& o)const {
            if (content == o.content) {
                return true;
            }
            return false;
        }

        bool operator !=(const Iterator& o)const {
            return !(*this == o);
        }
    };


    Array(const size_t s) :_size(s) {
        _data = new T[_size]();
        _start = new Iterator(_data);
    }

    Array(const Array& o) :_size(o._size), _data(o._data), _start(o._start) {}

    Array(const std::initializer_list<T>& list) :_size(list.size()) {
        auto start = list.begin();
        auto fin = list.end();

        _data = new T[_size];

        size_t index = 0;
        while (start != fin) {
            _data[index++] = *start++;
        }

        _start = new Iterator(_data);
    }

    virtual ~Array() {
        cout << "~Array" << endl;
        delete[] _data;
    }

    Array<T>& operator= (const Array& o) {
        if (this != &o) {
            delete[] _data;

            for (size_t i = 0; i < o._size; ++i) {
                _data[i] = o._data[i];
            }
            _size = o._size;
        }

        return *this;
    }

    T& operator[](const size_t index) {
        if (index < _size) {
            return *_data[index];
        }
    }

    const size_t size()const {
        return _size;
    }

    Iterator begin() {
        return _start;
    }

    Iterator end() {
        return Iterator(_data + _size);
    }

};

int main() {
    Array<string> array({ "h","e","l","l","o" });

    for (Array<string>::Iterator i = array.begin(); i != array.end(); ++i)
        cout << **i << endl;
}

Thank you @rustyx for your help, Wasn't far from it, but realy thank you.

I will post my corrected and working code here in case it can help others.

#include <cstdlib>
#include <string>
#include <iostream>

using namespace std;


template<typename T>
class Array{

T* _data;
size_t _size;

public:

    class Iterator{
        T* content;

    public:
        explicit Iterator(T* value):content(value){}

        Iterator& operator++(){
            ++content;
            return *this;
        }

        T& operator*(){
            return *content;
        }

        bool operator ==(const Iterator& o)const{
            if(content == o.content){
                return true;
            }
            return false;
        }

        bool operator !=(const Iterator& o)const{
            return !(*this == o);
        }
    };


Array(const size_t s):_size(s){
    _data = new T[_size]();
}

Array(const Array& o):_size(o._size){
    _data = new T[_size];
    for (size_t i = 0; i < o._size; ++i) {
        _data[i] = o._data[i];
    }
}

Array(const std::initializer_list<T>& list):_size(list.size()){
    auto start = list.begin();
    auto fin = list.end();

    _data = new T[_size];

    size_t index = 0;
    while(start != fin){
        _data[index++] = *start++;
    }

}

virtual ~Array(){
    cout << "~Array" << endl;
    delete[] _data;
}

Array<T>& operator= (const Array& o){
    if(this != &o){
        delete[] _data;

        for (size_t i = 0; i < o._size; ++i) {
            _data[i] = o._data[i];
        }
        _size = o._size;
    }

    return *this;
}

T& operator[](const size_t index){
    if(index < _size){
        return *_data[index];
    }
}

const size_t size()const{
    return _size;
}

Iterator begin(){
    return Iterator(_data);
}

Iterator end(){
    return Iterator(_data + _size);
}

};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM