2011-01-31 4 views
4

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

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

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

Да, это должно быть. Честно говоря, нет ни одного ответа на этот вопрос, который всегда имеет смысл - иногда вам нужно лексическое сравнение, в других случаях это явная логическая ошибка. –

+0

@Jerry: Лексическое сравнение означало бы третий возможный результат: * true *. Однако я не * считаю, что два массива разного размера равны. – fredoverflow

+0

Если это для удовольствия и образования. Сделайте оба. –

ответ

1

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

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

5

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

+0

Как бы встроенный op ==, который всегда возвращает false, отрицательно влияет на производительность? –

+0

@Fred: Не совсем, я перефразировал ответ. –

+0

Как бы встроенный оператор op ==, который всегда возвращает false, не будет оцениваться во время компиляции (при условии компилятора)? –

4

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

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

1

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

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

0

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

1

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

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

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

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

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

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

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

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

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

+0

Хотя они разные типы, это не обязательно исключает сравнение, даже если это [SCAREy] (http://chat.stackoverflow.com/transcript/10?m=241740#241740). –

+0

@Fred: Нет, это не так. Но это должен быть намек на то, чтобы не делать это с помощью 'operator =()'. – sbi

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