C++ template parameters in method definitions

Do all method declarations in a class that has a template parameter need to be declared with that parameter? The compiler seems to want something like the following

// Queue.h
template <class ItemType>
class Queue
{
    Queue();
    ItemType dequeue();
    int count();
    /* ... other methods ... */
};
// Queue.cpp
template <class ItemType>
Queue<ItemType>::Queue()
{ /*...*/ }
template <class ItemType>
int Queue<ItemType>::count()
{/*...*/}
template <class ItemType>
ItemType Queue<ItemType>::dequeue()
{/* ... */}

Coming from Java/C#, this seems a bit redundant--I feel like I should be able to define the methods more like this:

int Queue::count() 

The signature does not reference ItemType, so we can omit it.

Queue::ItemType Queue::dequeue() 

The signature references ItemType, but the compiler knows that we're talking about the template parameter because we qualify the identifier with Queue::

Answers


Yes, you need to provide the template argument. Note that while it might look redundant, it is not. C++ templates are a much more powerful tool that Java generics, and they allow for specializations. That means that with a base template Queue there might be multiple implementations that match different template arguments and have different definitions. Alternatively, you can have a single Queue template with multiple specializations for some functions. These two situations require you to provide both the template argument list an the class template arguments:

// Just member specialization
template <typename T>
struct X {
   void foo() { std::cout << "generic\n"; }
};
// specialize just this member for `int`
template <>
void X<int>::foo() { std::cout << "int\n"; }
int main() {
   X<double> xd; xd.foo();  // generic
   X<int>    xi; xi.foo();  // int
}

// Class template specialization
template <typename T>
struct X {
   void foo();
}
template <typename T>
struct X<T*> {
   void bar();
}
template <typename T>
void X<T>::foo() { std::cout << "generic\n"; }
template <typename T>
void X<T*>::bar() { std::cout << "ptr\n"; }
int main() {
   X<int > xi; xi.foo();       // generic
   X<int*> xp; xp.bar();       // ptr
}

Need Your Help

Unable to upload and process image with CarrierWave and MiniMagick

ruby-on-rails imagemagick carrierwave minimagick

I am trying to implement image-upload with CarrierWave and MiniMagick. I was able to upload an image with carrierwave, but when I implemented MiniMagick to resize uploaded images, it returned this ...

iOS: get filenames from documents directory into NSMutableArray

ios path nsmutablearray nsfilemanager nsdocumentdirectory

Here is kind of an overview of what I'm trying to do. My app has a form on it, and the form data is saved as a .csv file in the documents directory. I want to parse through the documents directory ...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.