Comparing Arrays of Different Sizes

I am implementing my own version of boost::array for fun and education, and I'm just wondering: should I compare two arrays with different sizes of false, or will it be a type error?

 array<int, 3> a = {1, 2, 3}; array<int, 5> b = {1, 2, 3, 4, 5}; a == b // <--- false or type error? 
+4
source share
7 answers

In a language, various template instances are unrelated types. This means that technically the simplest thing is what boost :: array does: ignores the problem, the compiler will scream if you try to compare different sizes.

I was inclined to answer that it depends on the domain that you are modeling, but given that the size of the array is a compile-time constant, the user should know that both arrays are different from each other without even trying to compare. Even in the template code, if there is one size parameter, everything will fit on its own.

+1
source

It must be a type error. People who use boost::array select it over std::vector because they want evaluations (and crashes) at compile time, and not at run time.

+5
source

There can be no general answer to this question. It depends on the business logic of the code that compares the arrays.

But in general, if I don’t know what business logic comparing arrays is, I would return false . Arrays are different if they do not have the same size.

+4
source

If your array does not expand the base class, for example array<int> , then throw a type error, since your class function is based on strong typing. If you allowed polymorphism in size, then return false.

Moreover, what is the advantage of the operator, which in all cases will always return the same value?

+1
source

I think the problem is more general than a single == operator.

The == operator is closely related to != And may be attached to < , > , <= and >= .

The definition must be consistent among all of them, that is, either two arrays of different sizes can be compared (regardless of the comparison used), or this is not so.

I suspect both may be helpful:

  • compile-time error: you are warned that there is something suspicious here.
  • runtime-time false: you do not need to specialize all your template methods for different sizes.

But only one gives a warning at compile time, the other means that you hope to detect a problem at runtime (through testing). Therefore, I would provide a “safe” operator overload and a more detailed method for a “soft” comparison:

 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' } 

So you get the best of both worlds, I think:

  • Compilation caution warning
  • A compile-time error can be easily handled if it is intended to

Guideline: make it easy to understand and hard to make a mistake

+1
source

In C ++, array<int, 3> and array<int, 5> are different types, just as std::vector<int> and std::list<int> are different types. The fact that they are created from the same template is basically irrelevant.

Now you can view both sequences, and then comparison makes sense. For this, however, iterators are commonly used.

+1
source

Arrays of different sizes are not equal, and in your case you know this at compile time. Do not execute the equality operator for different sizes; it's pointless! You know that they are no longer equal!

0
source

Source: https://habr.com/ru/post/1337805/


All Articles