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