Preferred implementation of `Array::operator=(const Array & rhs)`
template &lt;typename T&gt;
bool JKArray&lt;T&gt;::operator=(const JKArray&lt;T&gt; &amp; rhs)

template &lt;typename T&gt;
void JKArray&lt;T&gt;::operator=(const JKArray&lt;T&gt; &amp; rhs)


Neither of them have the correct signature for a copy assignment. The correct signature for that operator is class_name &amp; class_name :: operator= ( const class_name &amp; ).

That already rules out abusing the return value to signal success or failure. If you want runtime errors, you got to do it with exceptions.

If you violate that signature, it makes common patterns such as chained assignment (a = b = c = {...};) impossible. This may break other templated libraries depending on your datatypes to adhere to the standards.

Especially returning a bool may cause rather unexpected side effects.




  Pro
  
  
  Most of the time, the array is often thought of as a static container (there are std::vector, etc. for dynamic containers).
  It's more efficient, because I do not have to reallocate; rather, I overwrite each element of the LHS.
  
  
  Con
  
  
  It's a hassle for the user to do the work himself if he does intend to have a variable-length Array, plus it would be inefficient.
  


That list is by no means complete. There are more aspects to cover:


Iterator invalidation

When you have to re-allocate the backing data structure, it would be trivial to keep all existing iterators valid for same-size copies, while the same feat is problematic for different sizes.
Heap vs stack allocation

For fixed size arrays, it's not even necessary to allocate them on the heap, sufficiently small arrays may as well be allocated straight on the stack. This is obviously impossible to do with the dynamically sized ones.
Array or Vector?

While you call it Array, if you make it re-sizable it behaves more like an std::vector rather than an std::array.
Size as part of the type?

As @Olzhas mentioned, it's an option to include the size of the backing array as a template parameter. This provides compile time checks for compatible or incompatible sizes. Whereby compile time checks - if applicable - are obviously to be preferred.

This would actually be how std::array does it.