C++, шаблонизировать T в std::pair <T, short>

Я хотел бы шаблонизировать "первый" тип std::pair, используя следующую конструкцию

template <typename T>
struct TPair
{
typedef std::pair <T, short> Type;
};

и создать вектор таких пар.

template <typename T>
struct TPairs
{
typedef std::vector <TPair <T> > Type;
};

Но этот код кажется испорченным для общего использования, и это неудобно:

TPair <double> ::Type my_pair (1.0, 0 ); //Create pairs
TPair <double> my_pair2 (1.0, 0 ); //Create object, needs a constructor

TPairs <double> ::Type pairs; //Create vector
TPairs <double> pairs2; //Create object

pairs.push_back(my_pair); //Need a constructor
pairs2.push_back(my_pair); //No push_back method for the structure...
....

Есть ли более простое и удобное решение?

4 ответа

Решение
template <typename T>
struct TPairs
{
  typedef std::vector <TPair <T> > Type;
};

Здесь есть проблема: вы создаете тип, который является вектором TPair<T>что на самом деле не то, что вы хотите. Вы хотите вектор TPair<T>::Type,

template <typename T>
struct TPairs
{
  typedef std::vector <typename TPair <T>::Type > Type;
};

Что касается ваших вариантов использования, помните, что эти две структуры, которые вы создали, предназначены только для имитации шаблона typedef, вам никогда не следует создавать их экземпляры вообще, просто используйте их Type член typedef. Так:

TPair <double> ::Type my_pair (1.0, 0 ); // Good, creates a std::pair
TPair <double> my_pair2 (1.0, 0 ); // Not good, does not create an std::pair


TPairs <double> ::Type pairs; //Good, creates a vector
TPairs <double> pairs2;       //Not good, doesn't create a vector

pairs.push_back(my_pair);   // Ok, does what you mean
pairs2.push_back(my_pair);  // Can't compile, the `TPairs` struct ins't a vector

Похоже, вам нужен " псевдоним шаблона", который, очевидно, был добавлен в стандарт с C++11. Синтаксис в вашем случае будет что-то вроде:

template <typename T>
using TPair = std::pair<T,short>;

template <typename T>
using TPairs = std::vector<TPair<T>>;

[Отказ от ответственности: я не пробовал это, так что это может быть чепуха.]

Почему не просто использовать наследование? Например:

template <typename T>
struct TPair : public std::pair< T, short >{};

template <typename T> 
struct TPairs : public std::vector< TPair< T > >  {};

Если вы любите приключения, вы можете просто унаследовать типы, которые вы хотите шаблонизировать, и предоставить подходящих конструкторов.:)

#include <utility> // forward

template<class T>
struct TPair
  : public std::pair<T, short>
{
private:
  typedef std::pair<T, short> base;

public:
  template<class U>
  TPair(U&& u, short s) // forwarding ctor
    : base(std::forward<U>(u), s) {}

  TPair(TPair const& other) // copy ctor
    : base(static_cast<base const&>(other)) {}

  TPair(TPair&& other) // move ctor
    : base(static_cast<base&&>(other)) {

  // and assignment operators... I'll leave those as an exercise
};

// and the same for TVector... again, I'll leave those as an exercise. :>
Другие вопросы по тегам