I have a template Graph class which uses an adjacency matrix (array of singly linked lists).

I need to be able to initialize the Graph with a size.

I guess it is done this way?

template <class T, int SIZE>
class Graph {


}

My problem is with member functions.

How do I declare a member function such as:

template <class T>
bool Graph<T, size>::AddVertex(T Data) {
}

the <T, size> above does not work. Also, do I need to do something like enum { size=SIZE }; within the class definition to be able to use the size argument in various member functions?

Thanks.

template <class T, int SIZE>
class Graph 
{
  bool AddVertex(T Data) ; 
  // ...
};

template <class T, int SIZE>
bool Graph<T, SIZE>::AddVertex(T Data)
{
  // ...
}
commented: Very helpful. +1

Duh! Thank you very much!

I am getting another error when instantiating a Graph object with an integer.

int numcourses;

Graph <Course, numcourses> graph;

"error- numcourses cannot appear in a constant-expression", yet if I use Graph <Course, 6> graph; it work fine. Any way to make it work with a variable?
Thanks!

> Any way to make it work with a variable?
no way (as a template parameter) if it is not a constant known at compile-time.

you could always do this:

template < typename T > class Graph 
{
  public : 
    explicit Graph( int size ) : SIZE(size) {}
    bool AddVertex(T Data) ; 
    // ...
  private: const int SIZE ;
};

template < typename T >
bool Graph<T>::AddVertex(T Data)
{
  // ...
}

Thanks again for your help!

The new way you posted is a bit hard to understand for me. When you use typename, do you actually mean typename, or should I replace it with class?

Also, how do I define/instantiate an object of the type you listed? I am not sure how I would specify the size in your case.

Thanks again!

> When you use typename, do you actually mean typename, or should I replace it with class?
in the context in which it is used, either typename or class will work. typename is preferred over class (class is there only to support legacy code).

> how do I define/instantiate an object of the type you listed?

int numcourses;
cin >> numcourses;
Graph<Course> graph(numcourses);

I understand now. Thanks.

Here is my last issue:

the only data member of the Graph is:

SinglyLinkedList<T> array;

it does not work if I add const int SIZE right before it. My guess is that I somehow need to initialize this list array within the explicit constructor above?

> SinglyLinkedList<T> array;
it does not work if I add const int SIZE right before it
number of elements in c style arrays have the same restrictions as template parameters;
they must be constants known at compile time.

the best way is to use a std::vector instead of an array eg.

template < typename T > class Graph 
{
  public : 
    explicit Graph( size_t size ) : SIZE(size), array(size) {}
    bool AddVertex(T Data) ; 
    // ...
  private: 
     const size_t SIZE ;
     std::vector<T> array ;
};

i have by now become aware that a lot of people think that arrays are easier to use than vectors; if this is a homework and your teacher happens to be a member of this unfortunate group, allocate the array dynamically. eg.

template < typename T > class Graph 
{
  public : 
    explicit Graph( size_t size ) : SIZE(size), array( new T[size] ) {}
    ~Graph() { delete[] array ; }
    bool AddVertex(T Data) ; 
    // ...
  private: 
     const size_t SIZE ;
     T* array ;
     Graph( const Graph<T>& ) ;
     void operator= ( const Graph<T>& ) ;
};

the third option is make the number of elements a constant known at compile time (not very flexible) and revert to the first version. enum { numcourses = 9 };

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.