C ++, шаблонизировать T в std :: pair <T, short> - PullRequest
3 голосов
/ 22 января 2012

Я хотел бы шаблонизировать "первый" тип 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 ]

3 голосов
/ 22 января 2012
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
3 голосов
/ 22 января 2012

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

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

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

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

1 голос
/ 22 января 2012

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

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

template <typename T> 
struct TPairs : public std::vector< TPair< T > >  {};
0 голосов
/ 22 января 2012

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

#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. :>
...