Сравнение массивов разного размера - PullRequest
4 голосов
/ 31 января 2011

Я реализую свой собственный вариант boost::array для развлечения и образования, и мне просто интересно: должно ли сравнение двух массивов разного размера давать ложь или это ошибка типа?

array<int, 3> a = {1, 2, 3};
array<int, 5> b = {1, 2, 3, 4, 5};

a == b   // <--- false or type error?

Ответы [ 7 ]

5 голосов
/ 31 января 2011

Это должна быть ошибка типа. Люди, которые используют boost::array, выбирают его вместо std::vector, потому что им нужна оценка (и ошибка) во время компиляции, а не во время выполнения.

4 голосов
/ 31 января 2011

Не может быть общего ответа на этот вопрос.Это зависит от бизнес-логики кода, который сравнивает массивы.

Но в целом, если я не знаю, что такое бизнес-логика, которая сравнивает массивы, я бы вернул false.Массивы различаются, если они не одного размера.

1 голос
/ 31 января 2011

В C ++ array<int, 3> и array<int, 5> - это разные типы, также как std::vector<int> и std::list<int> - это разные типы.Тот факт, что они создаются из одного шаблона, в основном не имеет значения.

Теперь вы можете просматривать обе последовательности как , и тогда сравнение будет иметь смысл.Однако для этого обычно используются итераторы.

1 голос
/ 31 января 2011

Я думаю, что проблема более общая, чем у единственного == оператора.

Оператор == тесно связан с != и, возможно, связан с <, >, <= и >=.

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

Я подозреваю, что оба могут быть полезны:

  • Ошибка во время компиляции: вы предупреждены, что здесь есть что-то подозрительное
  • время выполнения ложно: вам не нужно специализировать все методы вашего шаблона для работы с разными размерами.

Но только одно выдает предупреждение во время компиляции, другое подразумевает, что вы надеетесь обнаружить проблему во время выполнения (через тестирование). Поэтому я бы предоставил «безопасную» перегрузку оператора и более подробный метод для «мягкого» сравнения:

template <typename T, size_t M, size_t N>
bool soft_equal(array<T,M> const& lhs, array<T,N> const& rhs)
{
  if (M != N) { return false; }
  // comparison logic
}

template <typename T, size_t M>
bool operator==(array<T,M> const& lhs, array<T,M> const& rhs)
{
  return soft_equal(lhs,rhs); // count on the compiler to eliminate the 'if'
}

Таким образом, вы получаете лучшее из обоих миров, я думаю:

  • Неосторожный предупреждается при компиляции
  • Ошибка времени компиляции может быть легко устранена, если она предназначена

Рекомендация: упростить правильное понимание, а трудно ошибочное

1 голос
/ 31 января 2011

В языке различные экземпляры шаблонов являются несвязанными типами.Это означает, что технически самое простое, что нужно сделать, это то, что делает boost :: array: игнорируя проблему, компилятор будет кричать, если вы попытаетесь сравнить разные размеры.

Я был склонен ответить, что это зависит отдомен, который вы моделируете, но учитывая, что размер массива является постоянной времени компиляции, пользователь должен знать, что оба массива различаются, даже не пытаясь сравнивать.Даже в шаблонном коде, пока существует один параметр размера, все само встанет на свои места.

1 голос
/ 31 января 2011

Если ваш массив не предоставляет базовый класс, такой как array<int>, то выдает ошибку типа, поскольку функция вашего класса основана на строгой типизации.Если вы допускаете полиморфизм по размеру, тогда возвращайте false.

Более конкретно, в чем преимущество наличия оператора, который во всех случаях всегда будет возвращать одинаковое значение?

0 голосов
/ 31 января 2011

Массивы разных размеров не равны, и в вашем случае вы это знаете во время компиляции.Не используйте оператор равенства для разных размеров;это бессмысленно!Вы знаете, что они уже не равны!

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