Garrett
Garrett

Reputation: 11725

C++: initializing template constructor/routine declared in header file?

I have a template defined in my header file as follows:

 template<typename T> class BoundedBuffer {
    unsigned int size;
    T entries[];
  public:
    BoundedBuffer( const unsigned int size = 10 );
    void insert( T elem );
    T remove();
};

However, when I try to initialize the constructor:

BoundedBuffer<T>::BoundedBuffer( const unsigned int size = 10 ) size(size) {
    // create array of entries
    entries = new T[size];

    // initialize all entries to null
    for(int i = 0; i < size; i++)
        entries[i] = null;
}

I get the following error (the first line of the previous code block is 17):

q1buffer.cc:17: error: âTâ was not declared in this scope
q1buffer.cc:17: error: template argument 1 is invalid
q1buffer.cc:17: error: expected initializer before âsizeâ

Upvotes: 0

Views: 1521

Answers (3)

Salvatore Previti
Salvatore Previti

Reputation: 9050

The right syntax is:

template <typename T>
BoundedBuffer<T>::BoundedBuffer(const unsigned int size) : size(size) {
    // create array of entries
    entries = new T[size];

    // initialize all entries to null
    for(int i = 0; i < size; i++)
        entries[i] = null;
}

Note that optional parameters should not be declared in functions definitions but ony in functions declarations.

class aaa
{
    // declaration
    void xxx(int w = 10);
};

// definition
void aaa::xxx(int w)
{
    ...
}

Note that everything for templated class should stay in H files.

"They must be in the same translation unit. It is quite common in some libraries to separate the template implementation into a .tpp (or some other extension) file that is then included in the .h where the template is declared." as Michael Price said.

Templates are not normal types and they cannot be linked. They are instantiated only when requested.

Note that constructors fields initializers need the ":" character.

class MyClass
{
public:
    int x;

    MyClass() : x(10) { /* note that i used : character */ }
};

Upvotes: 4

K-ballo
K-ballo

Reputation: 81349

Your declaration should be:

template< typename T >
BoundedBuffer<T>::BoundedBuffer( const unsigned int size ) : size( size ) {...}

Note that it also has to be in the header file, as mentioned by @Dean Povey.

Upvotes: 1

Dean Povey
Dean Povey

Reputation: 9446

You have to implement all methods of the template in the header, because users of the template need to be able see those methods to instantiate it for a given type.

Upvotes: 1

Related Questions