Согласованные типы шаблонов - PullRequest
5 голосов
/ 19 ноября 2011

Задача

Рассмотрим следующий класс

template <typename T>
struct A
{
   T x;
};

Теперь, другой класс шаблонируется так:

template <typename T, typename U>
class B
{
   protected:
      std::vector<U> arr;

   public:
      T get_x(unsigned int p) { return arr[p].x; }
};

Я хотел бы получить доступ к полю A<T>::x из B<T, A<T>>::get_x() и вернуть его без изменений (т.е. сохранить его тип как T). Мое плохое знание шаблонов говорит, что это требует знания типа andof T, это должен быть один из параметров шаблона class B. Однако это позволяет объявить что-то непоследовательное, например B<int, A<double>>, и в целом звучит как ненужное повторение.

Вопросы

  1. Является ли то, что я написал, примером плохой практики программирования? Как это должно быть написано?
  2. Есть ли возможность вывести тип T из A<T>::x и избежать двух типов шаблонов? Это похоже на повторение, поэтому я не уверен, есть ли там богобоязненное, стандартное решение или нет.

Для этого я использую GCC 4.6.2 с -std = c ++ 0x.

1 Ответ

4 голосов
/ 19 ноября 2011

Я бы предложил подход, принятый Стандартной библиотекой. Определите вложенный тип.

template <typename T>
struct A
{
   typedef T value_type; //this is nested type to be used by B
   T x;
};

//this is another class added by me, just to demonstrate the genericity
template <typename T>
struct C
{
   typedef T value_type; //this is nested type to be used by B
   T x;
};

template <typename T>
class B
{
      typedef typename T::value_type value_type;  //get the nested type
   protected:
      std::vector<T> arr;

   public:
      value_type get_x(unsigned int p) { return arr[p].x; }
    //^^^^^^^^^ note this
};

Использование:

 B<A<int>> ba;    //'>>' if C++11, otherwise use '> >' (separate them by space)
 B<C<double>> bc; //works for C class template as well
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...