user2836797
user2836797

Reputation:

Get the typename T from outside the template class

I have a vector that I want to wrap in some additional functionality:

template <typename T>
class PersistentVector : PersistentObject
{
  private:
    std::vector<T> values;

  public:
    virtual void read();

Now, how would I go about defining read() outside the class if it must know the typename T?

First try:

void PersistentVector::read()
{
  // How can I get the iterator type?
  typedef std::vector<T>::iterator it_type;  // vector cannot be resolved
}

Second try:

// error: Member declaration not found
template <typename T>
void PersistentVector::read()
{
  typedef std::vector<T>::iterator it_type;  // no error
}

Upvotes: 3

Views: 294

Answers (2)

Marco A.
Marco A.

Reputation: 43662

It is mandatory that the type of the template is known at the POI (point-of-instantiation) before linking time, so you should either put that into the header (and watch out for the typename keyword, it is required in that case):

#pragma once

#include <vector>

template <typename T>
class PersistentVector
{
  private:
    std::vector<T> values;

  public:
    virtual void read() {
      typedef typename std::vector<T>::iterator it_type;
    }
};

Or do something like an explicit instantiation

.h file

#pragma once

#include <vector>

template <typename T>
class PersistentVector
{
  private:
    std::vector<T> values;

  public:
    virtual void read();
};

.cpp file

#include "headerfile.h"

template <typename T>
void PersistentVector<T>::read()
{
  typedef typename std::vector<T>::iterator it_type; 
}

template class PersistentVector<int>;

Upvotes: 1

juanchopanza
juanchopanza

Reputation: 227410

Your second try is almost there. You got the syntax slightly wrong, and are missing a typename. Note the PersistentVector<T>:::

template <typename T>
void PersistentVector<T>::read()
{
  typedef typename std::vector<T>::iterator it_type;  // no error
}

Note that this definition must be accessible to any code using it. Usually this means it has to be in the header file, or in a file included by the header.

Alternatively, you can put the method definition inside of the class definition:

public:
  virtual void read()
  {
    typedef typename std::vector<T>::iterator it_type;
  }

Upvotes: 5

Related Questions