Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I return a dependent type from templated class method?

Let's say I have a class based on a template ThingType. In the header, I use this to typedef a dependent type VectorThingType. I'd like to return this from a method GetVectorOfThings(). If I set VectorThingType as the return type, I get a Does not name a type error, as the type wasn't defined in this scope. Is there any way to do this without duplicating the code in the typedef?

#include <vector>
#include <iostream>

template< typename ThingType >
class Thing
{
public:

 ThingType aThing;
 typedef std::vector< ThingType > VectorThingType;
 VectorThingType GetVectorOfThings();

Thing(){};
~Thing(){};

};

template< typename ThingType >
//VectorThingType // Does not name a type 
std::vector< ThingType > // Duplication of code from typedef
Thing< ThingType >
::GetVectorOfThings() {
  VectorThingType v;
  v.push_back(this->aThing);
  v.push_back(this->aThing);
  return v;
}
like image 339
sudo make install Avatar asked Apr 03 '15 17:04

sudo make install


People also ask

What is an instanced template class?

Template classes are instanced in the same way template functions are -- the compiler stencils out a copy upon demand, with the template parameter replaced by the actual data type the user needs, and then compiles the copy. If you don’t ever use a template class, the compiler won’t even compile it.

What does the “template class” command do?

The “template class” command causes the compiler to explicitly instantiate the template class. In the above case, the compiler will stencil out both Array<int> and Array<double> inside of templates.cpp. Because templates.cpp is inside our project, this will then be compiled.

Why use a template class for container classes?

Template classes are ideal for implementing container classes, because it is highly desirable to have containers work across a wide variety of data types, and templates allow you to do so without duplicating code.

Do I need a template declaration for every member function?

This isn’t necessary, but new programmers typically stumble when trying to do this for the first time due to the syntax, so an example is instructive. Each templated member function defined outside the class declaration needs its own template declaration.


2 Answers

template< typename ThingType >
auto // <-- defer description of type until...
Thing< ThingType >
::GetVectorOfThings()
-> VectorThingType // <-- we are now in the context of Thing< ThingType >
{
  VectorThingType v;
  v.push_back(this->aThing);
  v.push_back(this->aThing);
  return v;
}
like image 157
Richard Hodges Avatar answered Sep 24 '22 06:09

Richard Hodges


Just came across another answer to this question, which doesn't involve c++11.

template< typename ThingType >
typename Thing< ThingType >::VectorThingType
Thing< ThingType >
::GetVectorOfThings()
{
  VectorThingType v;
  v.push_back(this->aThing);
  v.push_back(this->aThing);
  return v;
}

Basically involves assuring the compiler that you are, in fact, dealing with a type via typename and then properly scoping the type using Thing< ThingType >::. Could be useful if you are stuck with c++03 for some reason.

like image 22
sudo make install Avatar answered Sep 21 '22 06:09

sudo make install