2017-02-16 10 views
0

У меня есть следующий класс шаблона:Шаблона сравнение оператора

template<int size, typename Type> 
class Matrix { 
    public: 
     Matrix(); 
     ... 
     Type operator()(int row, int column) {...} 
    private: 
     std::array<Type, size*size> _array; 
} 

И я хочу, чтобы перегрузить оператор equal to сравнения сравнить Matrix объектов:

template <int size, typename LeftType, typename RightType> 
bool operator ==(const Matrix<size, LeftType> & left, const Matrix<size, RightType> & right) { 
    for (int i = 0; i < size; ++i) { 
     for (int j = 0; j < size; ++j) { 
      ... 
     } 
    } 
} 

Проблема заключается в том, что сравнение целочисленных типов и реальных типы совершенно разные:

real case:

template <int size, typename LeftType, typename RightType> 
bool operator ==(const Matrix<size, LeftType> & left, const Matrix<size, RightType> & right) { 
    for (int i = 0; i < size; ++i) { 
     for (int j = 0; j < size; ++j) { 
      if (qFuzzyIsNull(left(i, j)) || qFuzzyIsNull(right(i, j))) { 
       if (!qFuzzyCompare(left(i, j) + 1, right(i, j) + 1)) { 
        return false; 
       } 
      } else { 
       if (!qFuzzyCompare(left(i, j), right(i, j))) { 
        return false; 
       } 
      } 
     } 
    } 
    return true; 
} 

(Я использую Qt-х qFuzzyCompare и qFuzzyIsNull)

integer case:

template <int size, typename LeftType, typename RightType> 
bool operator ==(const Matrix<size, LeftType> & left, const Matrix<size, RightType> & right) { 
    for (int i = 0; i < size; ++i) { 
     for (int j = 0; j < size; ++j) { 
      if (left(i, j) != right(i, j)) { 
       return false; 
      } 
     } 
    } 
    return true; 
} 

Как включить integer case если оба LeftType и RightType целое и позволяют real case если по крайней мере один LeftType или RightType реально ?

+4

перегрузки '=' 'для реального type', так что вы можете использовать ту же функцию для обоих!? – NathanOliver

+0

Вы можете использовать специализированную специализацию и написать одну версию escpacally для LeftType и RightType = int. Поэтому специальная функция всегда будет вызываться, если оба они целые. Также можно подумать о добавлении явного для этого случая, если не требуется конверсия. – Aeonos

+2

'шаблон специализации' - это то, что вы ищете. Но @NathanOliver прав, логика (вложенный цикл) одинакова, и может быть лучше перегрузить operator! = Для реального типа. –

ответ

1

Как об этом:

template <int size, typename LeftType, typename RightType> 
bool operator ==(const Matrix<size, LeftType> & left, const Matrix<size, RightType> & right) { 
    for (int i = 0; i < size; ++i) { 
     for (int j = 0; j < size; ++j) { 
      if (not is_equal(left(i,j), right(i,j)) { 
       return false; 
      } 
     } 
    } 
    return true; 
} 

, а затем вы либо определить несколько перегруженных вариантов is_equal или сделать is_equal шаблон и определить его специализации, как

template<class T> 
bool is_equal(const T a, const T b); 

template<> 
bool is_equal<int>(const int a, const int b){ 
    return a == b; 
} 

template<> 
bool is_equal<real>(const real a, const real b){ 
    ... 
} 

(или в качестве шаблона по два типы, если это может произойти)

Конечно, вы можете специализировать сам оператор, но это означает, что вам придется писать один и тот же код заново без каких-либо шанс, что вы его повторно будете использовать. Между тем, is_equal может стать обычным инструментом в вашей программе.

(примечание: is_equal является несколько основным именем, поэтому он должен быть в пространстве имен, очевидно)

 Смежные вопросы

  • Нет связанных вопросов^_^