Наследование классов шаблона C ++ и использование операторов - PullRequest
2 голосов
/ 09 ноября 2011

У меня есть класс шаблона, который определяет операторы, которые работают с параметрами шаблона.У меня есть другой класс, который наследуется от этого класса, и я хочу, чтобы операторы были унаследованы, конечно.

Учтите это:

template <typename T>
class A
{
public:
  A(const T& x) : x_(x) {}
  A operator-(const A& other) 
  { 
    A r(*this);
    r.x_ -= other.x_;
    return r;
  }

  T x() const { return x_; }

private:
  T x_;
};

template <typename T>
class B : public A<T>
{
  // additional stuff here
};

Я не могу использовать ни один из операторов, объявленных в A для объектов типа B.

Пример:

int main()
{
  // Fine
  A<int> a(5);
  A<int> b(2);
  A<int> c = a - b;
  std::cout << c.x() << std::endl;

  // Won't compile :( 
  B<int> d(5);
  B<int> e(2);
  B<int> f = d - e;
  std::cout << f.x() << std::endl;

  return 0;
}

Будет вызывать следующую ошибку: ошибка: запрошено преобразование из 'A' в нескалярный тип 'B'

Есть ли способ, которым это может работать?Я действительно хочу избежать переписывания всего кода (который был бы точно таким же) в классе B.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 09 ноября 2011

Проблема не в вызове оператора, а в создании B из возвращаемого значения, которое является A.

Если B не содержит никаких данных, кроме базового класса A, вы можете предоставить конструктор для B из A:

template <typename T>
class B : public A<T>
{
public:
     B(const T& x) : A<T>(x) {}
     B(const A<T>&x) : A<T>(x) {}
  // additional stuff here
};

Если B содержит свои собственные данные, то вам обязательно нужно реализовать operator- для обработки этих полей данных?

0 голосов
/ 09 ноября 2011

Когда я пытаюсь это сделать, Visual Studio выдает мне ошибку cannot convert from 'A<T>' to 'B<T>'

Поэтому я попытался изменить тип переменной f с B<int> на A<int>, и она скомпилирована правильно.Вот что у меня есть:

int main()
{
  // Fine
  A<int> a(5);
  A<int> b(2);
  A<int> c = a - b;
  std::cout << c.x() << std::endl;

  // does compile :)
  B<int> d(5);
  B<int> e(2);
  A<int> f = d - e;
  std::cout << f.x() << std::endl;

  return 0;
}

Однако я не думаю, что это то, что вы хотите, потому что, если вы нашли способ преобразовать f из B в A, вы обнаружите, что все элементы данных специфичныдо Б было стерто.Если вы думаете о том, что процессор делает под капотом, это имеет смысл.Когда он видит, что типом возврата operator- является A, он возвращает ровно sizeof(A) байтов данных.Любые дополнительные данные поверх этого (такие как данные, связанные с B) отсекаются.Поэтому для безопасности компилятор скажет вам, что вам не повезло, если вы попытаетесь поместить возвращаемое значение в переменную типа B.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...