C++ template specialisation friend iterator error: invalid use of incomplete type

Lucian Gabriel Popescu

For a project I'm working at, I've created a C++ library that encapsulates data structures. For each data structure, I've created custom iterators to navigate through data elegantly. Everything went fine until I've tried template specialization on those classes, when I stumbled upon this build error: error: invalid use of incomplete type.

I've banged my head for more than a week on this and found nothing helpful on the net, so I thought maybe some of you can help me with this...

The whole problem simplified:

template<typename T>
class DataStructureIterator;
// OK
template<typename T>
class DataStructure {
    friend class DataStructureIterator<T>;
    public:
        typedef DataStructureIterator<T> iterator;

        ...

        iterator begin() {
            return iterator(this);
        }

        iterator end(){
            return iterator(count);
        }

};
// ERROR: "Invalid use of incomplete type" (on ANY specialization attempt)
template<>
class DataStructure<double> {
    friend class DataStructureIterator<double>;
    public:
        typedef DataStructureIterator<double> iterator;

        ...

        iterator begin() {
            return iterator(this);
        }

        iterator end(){
            return iterator(count);
        }

};

template<typename T>
class DataStructureIterator { ... }

Example:

template<typename T>
struct DoublyLinkedListEntry {
    T value;
    DoublyLinkedListEntry* next;
    DoublyLinkedListEntry* previous;
};

template<typename T>
class DoublyLinkedListIterator;

template<typename T>
class DoublyLinkedList {
    friend class DoublyLinkedListIterator<T>;
    public:
        typedef DoublyLinkedListIterator<T> iterator;

        DoublyLinkedList() {
            head = nullptr;
            tail = nullptr;
            count = 0;
        }

        ~DoublyLinkedList() {
            empty();
        }

        void add(const T& value) {
            DoublyLinkedListEntry<T>* element = new DoublyLinkedListEntry<T>;
            element->value = value;
            element->next = nullptr;
            element->previous = tail;
            if(head==nullptr) {
                head = element;
            } else {
                tail->next = element;
            }
            tail = element;
            ++ count;
        }

        iterator begin() {
            return iterator(this);
        }

        iterator end(){
            return iterator(count);
        }
    private:
        void empty(){
            DoublyLinkedListEntry<T>* temp = head;
            DoublyLinkedListEntry<T>* del = temp;
            while(del != nullptr) {
                temp = temp->next;
                delete del;
                del = temp;
            }
        }

        DoublyLinkedListEntry<T>* head;
        DoublyLinkedListEntry<T>* tail;
        std::size_t count;
};

template<>
class DoublyLinkedList<double> {
    friend class DoublyLinkedListIterator<double>;
    public:
        typedef DoublyLinkedListIterator<double> iterator;

        DoublyLinkedList() {
            head = nullptr;
            tail = nullptr;
            count = 0;
        }

        ~DoublyLinkedList() {
            empty();
        }

        void add(double& value) {
            DoublyLinkedListEntry<double>* element = new DoublyLinkedListEntry<double>;
            element->value = value;
            element->next = nullptr;
            element->previous = tail;
            if(head==nullptr) {
                head = element;
            } else {
                tail->next = element;
            }
            tail = element;
            ++ count;
        }

        iterator begin() {
            return iterator(this);
        }

        iterator end(){
            return iterator(count);
        }
    private:
        void empty(){
            DoublyLinkedListEntry<double>* temp = head;
            DoublyLinkedListEntry<double>* del = temp;
            while(del != nullptr) {
                temp = temp->next;
                delete del;
                del = temp;
            }
        }

        DoublyLinkedListEntry<double>* head;
        DoublyLinkedListEntry<double>* tail;
        std::size_t count;
};

template<typename T>
class DoublyLinkedListIterator {
    public:
        DoublyLinkedListIterator(){
            list = nullptr;
            current_item = nullptr;
            offset = 0;
        }

        DoublyLinkedListIterator(DoublyLinkedList<T>* list){
            this->list = list;
            current_item = list->head;
            offset = 0;
        }

        DoublyLinkedListIterator(std::size_t total){
            list = nullptr;
            current_item = nullptr;
            offset = total;
        }

        ~DoublyLinkedListIterator(){}

        const T operator*(){
            return current_item->value;
        }

        bool operator!=(const DoublyLinkedListIterator<T>& it) const {
            return offset!=it.offset;
        }

        DoublyLinkedListIterator<T>& operator++(){
            if(current_item!=nullptr) {
                current_item = current_item->next;
            }
            ++offset;
            return *this;
        }

    private:
        DoublyLinkedList<T>* list;
        DoublyLinkedListEntry<T>* current_item;
        std::size_t offset;
};

Build error:

In file included from ../src/Learning.cpp:11:0:
../src/DoublyLinkedList.h: In member function ‘DoublyLinkedList<double>::iterator DoublyLinkedList<double>::begin()’:
../src/DoublyLinkedList.h:107:20: error: return type ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’ is incomplete
   iterator begin() {
                    ^
../src/DoublyLinkedList.h:108:24: error: invalid use of incomplete type ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’
    return iterator(this);
                        ^
../src/DoublyLinkedList.h:22:7: error: declaration of ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’
 class DoublyLinkedListIterator;
       ^
../src/DoublyLinkedList.h: In member function ‘DoublyLinkedList<double>::iterator DoublyLinkedList<double>::end()’:
../src/DoublyLinkedList.h:111:17: error: return type ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’ is incomplete
   iterator end(){
                 ^
../src/DoublyLinkedList.h:112:25: error: invalid use of incomplete type ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’
    return iterator(count);
                         ^
../src/DoublyLinkedList.h:22:7: error: declaration of ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’
 class DoublyLinkedListIterator;
R Sahu

The error message is pretty clear.

class DoublyLinkedListIterator<double> is an incomplete type when you try to create instances of the class in the following functions:

    iterator begin() {
        return iterator(this);
    }

    iterator end(){
        return iterator(count);
    }

You can resolve this using either of the following methods.

  1. Move the definition of template<typename T> class DoublyLinkedListIterator before the definition of template<> class DataStructure<double>.

  2. Don't define the above functions inline. Only declare them. Define them after the definition of template<typename T> class DoublyLinkedListIterator.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Template class and 'invalid use of incomplete type' error

From Dev

Invalid use of incomplete type for partial template specialization c++

From Dev

c++ Friend function not recognised as friend with template specialisation

From Dev

Invalid use of incomplete type for named template argument

From Dev

C++17 optional tree, error: invalid use of incomplete type

From Dev

GCC compiler error when dealing with template classes 'error:invalid use of incomplete type template'

From Dev

"invalid use of incomplete type" for const function pointer type as template argument

From Dev

invalid use of non-static data member error with template friend functions c++

From Dev

Invalid use of incomplete type and expected type-specifier before error in C++

From Dev

Error using Eigen: invalid use of incomplete type ‘const class Eigen

From Dev

error: invalid use of incomplete type 'struct std::hash<>'

From Dev

Error with Eigen vector logarithm invalid use of incomplete type

From Dev

Qt error Invalid use of incomplete type 'class UI::FrameLess'

From Dev

Invalid use of incomplete type "class"

From Dev

Template specialisation for any pointer type

From Dev

Incomplete type in friend function

From Dev

C++ Template specialisation - illegal type for non-type template parameter '__formal

From Dev

variadic variadic template template specialisation error

From Dev

Forward declaration of class / Invalid use of incomplete type

From Dev

Invalid use of incomplete type with with 2 related classes

From Dev

Invalid use of incomplete type, reference vs pointer

From Dev

"invalid use of incomplete type". Solving circular dependencies

From Dev

GCC tuple "invalid use of incomplete type"

From Dev

Error: Variadic template class has incomplete type

From Dev

Error: "invalid use of incomplete type ‘RSA {aka struct rsa_st}" in OpenSSL 1.1.0

From Dev

Invalid use of incomplete type class error when inheriting from class defined externally

From Dev

How do I solve "[Error] invalid use of incomplete type 'class SLLNode'" Linked Lists

From Dev

error: invalid use of undefined type struct in C

From Dev

Typedef C Struct: invalid use of incomplete typedef

Related Related

  1. 1

    Template class and 'invalid use of incomplete type' error

  2. 2

    Invalid use of incomplete type for partial template specialization c++

  3. 3

    c++ Friend function not recognised as friend with template specialisation

  4. 4

    Invalid use of incomplete type for named template argument

  5. 5

    C++17 optional tree, error: invalid use of incomplete type

  6. 6

    GCC compiler error when dealing with template classes 'error:invalid use of incomplete type template'

  7. 7

    "invalid use of incomplete type" for const function pointer type as template argument

  8. 8

    invalid use of non-static data member error with template friend functions c++

  9. 9

    Invalid use of incomplete type and expected type-specifier before error in C++

  10. 10

    Error using Eigen: invalid use of incomplete type ‘const class Eigen

  11. 11

    error: invalid use of incomplete type 'struct std::hash<>'

  12. 12

    Error with Eigen vector logarithm invalid use of incomplete type

  13. 13

    Qt error Invalid use of incomplete type 'class UI::FrameLess'

  14. 14

    Invalid use of incomplete type "class"

  15. 15

    Template specialisation for any pointer type

  16. 16

    Incomplete type in friend function

  17. 17

    C++ Template specialisation - illegal type for non-type template parameter '__formal

  18. 18

    variadic variadic template template specialisation error

  19. 19

    Forward declaration of class / Invalid use of incomplete type

  20. 20

    Invalid use of incomplete type with with 2 related classes

  21. 21

    Invalid use of incomplete type, reference vs pointer

  22. 22

    "invalid use of incomplete type". Solving circular dependencies

  23. 23

    GCC tuple "invalid use of incomplete type"

  24. 24

    Error: Variadic template class has incomplete type

  25. 25

    Error: "invalid use of incomplete type ‘RSA {aka struct rsa_st}" in OpenSSL 1.1.0

  26. 26

    Invalid use of incomplete type class error when inheriting from class defined externally

  27. 27

    How do I solve "[Error] invalid use of incomplete type 'class SLLNode'" Linked Lists

  28. 28

    error: invalid use of undefined type struct in C

  29. 29

    Typedef C Struct: invalid use of incomplete typedef

HotTag

Archive