Нет жизнеспособного преобразования из массива <float>в массив <int> - PullRequest
3 голосов
/ 13 февраля 2020
#include <iostream>
using namespace std;

template<class T>
class Array {
public: // should be private, big ignore that
   int n;
   T *arr;
public:
   Array(int sz, T initValue) {
      n = sz;
      arr = new T[n];
      for (int i=0; i<n; i++) arr[i] = initValue;
   }

   Array& operator = (const Array& b) {
      if (this!=&b) {
         delete[] arr;
         n = b.n;
         arr = new T[n];
         for (int i=0;i<n;i++) arr[i] = b.arr[i];
      }
      return *this;
   }

   Array operator + (const Array& b) {
      Array res(n, 0);
      for (int i=0; i<n;i++) res.arr[i] = arr[i] + b.arr[i];
      return res;
   }
};

int main()
{
   Array<double> a(10, 1); //Array<double> b(10, 2); // this works
   Array<int> b(10, 2);
   a = b; // error
   for (int i=0; i<10; i++) cout << i << " " << a.arr[i] << "\n";

   Array<double> c(10,0);
   c = a + b; // error if b is <int>, runs if b is <double>
   c = a - b;
   c = a * b;
}

Итак, у меня есть шаблонный класс, который может принимать int, float, double, ...

Интуитивно, Array<double> a; Array<int> b; a = b; должно быть возможным, потому что поэлементно мы можем сделать a[i] = b[i]. Однако, у меня ошибка преобразования, потому что чего-то не хватает.

Как я могу сделать возможным a = b;? Спасибо.

Редактировать: дело не в создании массива. Это может быть Matrix, 3dArray, et c. Речь идет о присвоении float template и int template. Вы также можете заменить int на float, а float на highPrecisionFloat, например.

Edit 2: Я забыл упомянуть, мне нужен не только оператор =, но оператор + (и - * /, et c) также. Если я использую ответ @churill, я должен сделать это для каждого оператора. Как я могу сделать преобразование из Array в Array неявным?

1 Ответ

1 голос
/ 13 февраля 2020

В шаблоне класса

template<class T>
class Array { ... }

Идентификатор Array фактически относится к Array<T>. Вам нужно будет сделать operator== шаблоном, и вы, вероятно, захотите добавить явное приведение:

template<typename TOther>
Array<T> &operator = (const Array<TOther>& b) {
    if constexpr (std::is_same<T, TOther>::value) {
        // only check for self-assignment T and TOther are the same type
        if (this == &b)
        {
            return *this;
        }
    }

    delete[] arr;
    n = b.n;
    arr = new T[n];
    for (int i=0;i<n;i++) 
    arr[i] = static_cast<T>(b.arr[i]);

    return *this;
}

Обратите внимание, что std::is_same из заголовка type_traits.

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