how to write definition head for a template function that returns enum.
I got a template funciton List<List_entry>::print_List(){code..} but I dont get how to return an enum.
My current head is :

template<class List_entry>  List<List_entry>::Error_code List<List_entry>::put(const List_entry &x){code..}

but it errors me that I need 'typename' before 'List<List_entry>::Error_code' because 'List<List_entry>' is a dependent scope. I dont get what that means. Help please

Recommended Answers

All 5 Replies

What is Error_code? Is the the enum type? Can you post your class?

It means exactly what it says, that you need to put typename before List<List_entry>::Error_code, as so:

template<class List_entry> 
typename List<List_entry>::Error_code
  List<List_entry>::put(const List_entry &x)
{
  code..
}

The reason for this is that List<List_entry>::Error_code is a dependent type. Simply put, because List_entry is a template argument, when the compiler first passes through that code, it does not know what List_entry is, because it could be anything, and therefore, it cannot assume anything about List<List_entry> because it could be a specialization of general template for some special type of List_entry. Therefore, anything that is drawn from List<List_entry> is dependent on what List<List_entry> actually is or what it actually contains. So, when you simply write List<List_entry>::Error_code, the compiler cannot verify what Error_code is, and especially, it cannot check whether it is a type (like an enum type, or some other nested class or typedef inside List) or whether it is a member function of List (i.e., you could have a member function called Error_code is the List class template, and therefore List<List_entry>::Error_code would have a very different meaning (pointer to member function)). So, you need to add the keyword typename in front of it to tell the compiler that this expression is expected (once List_entry is known) to be a type, because otherwise, the compiler must assume it is a member function. In this particular case, having a member function as a return type does not make any sense, and that's why the compiler can tell you that you forgot to write typename in there, but the compiler is not allow (according to standard rules) to compile this code, and therefore, gives you this error.

Dealing with dependent names is something that you will have to get used to when working with templates. You have to sort of put yourself in the compiler's shoes and understand why and where ambiguities like these might arise. But until you understand them well enough, you can simply work by a kind of trial and error, just try to compile, and then add typename keywords (and sometimes also template keywords) when the compiler gives you trouble. At first, that's all I did, and it works fine (except that it's a bit tedious), but eventually I learned to understand this and now I know exactly where those keywords are needed and why.

now, i tried that aproach and it removed that error, and got a new one. Code :

.h :

#ifndef LIST_H
    #define LIST_H
    #include <Node.h>


    template <class List_entry>

    class List
    {
        public:

             enum Error_code {succes,overflow,underflow,range_error_code};

        private:
            int counter;
            Node<List_entry> *head;
            Node<List_entry> *set_position(int position)const;

        public :

            List(); // constructor
           ~List(); // destructor
            Error_code put(const List_entry &x);
            void print_List();
           //List (const List<List_entry> &cpy); // copy constructor
           //void operator= (const List<List_entry> &cpy);
            int size_of_list()const;
            //bool full()const;
            bool empty_list()const;
            //void clear_list();
            //void traverse (void(*visit)(List_entry&));
            //Error_code put(int position, const List_entry &x);
            //Error_code fetch(int position, List_entry &x);
            //Error_code retrieve(int position, List_entry &x)const;
            //Error_code replace_element(int position,const List_entry &x);


    };

    #endif // LIST_H

.cpp :

#include "List.h"
#include<cstddef>
#include <iostream>

template<class List_entry> List<List_entry>::List()         // creates empty list
{
        head = NULL;
        counter = 0;
}

template<class List_entry> typename List<List_entry>::Error_code List<List_entry>::put(const List_entry &x){

   if(size_of_list() > 50) return overflow;  // error check

   if(head == NULL)
   head = new_Node(x);

   else{

    Node<List_entry> *node = newNode(x);
    node->p_next = head;
    head = node;

   }


}

template<class List_entry> void List<List_entry>::print_List(){


    Node<List_entry> *q = head;

    while(q != NULL){

       std::cout<< q->value<<std::endl;
       q = q->p_next;
    }

}

template<class List_entry> bool List<List_entry>::empty_list()const{

    if(counter == 0) return true;
    else return false;

}

template<class List_entry> int List<List_entry>::size_of_list()const{ return counter;}

template<class List_entry> Node<List_entry>* List<List_entry>::set_position(int position)const{

     Node<List_entry> *q;                  // return a pointer to a node in a specified position
     q = head;

     for(int i = 0;i < position; i++){

        q = q->p_next;
    }

    return q;

}

main :

#include <iostream>
#include "List.h"


using namespace std;

int main()
{

    List<int> nino_list;
    nino_list.put(3);
    nino_list.put(4);
    nino_list.put(12);
    nino_list.put(14);
    nino_list.print_List();

}

as you can see am just trying to add some elements and print them. I starded with templates so am bit confused. when i write code u posted I get this error : undefined reference to `List<int>::put(int const&).

I realize its my job to figure out this but I cant understand, cause it all seems ok.

You cannot put the definitions (implementations) of function templates (or functions of class templates) in a separate cpp file. The definitions of templates must be visible to the compiler in order for it to compile them for the specific types you are using as template arguments. The point is, you cannot compile them separately and then link them together. You have to put the definitions in the header file. Read more here.

Thanks, solved the problem by puting it all in one file. all the best

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.