enable_if with copy constructors

Ignoring defaults, the signature of both of those constructors is

template <size_t N, typename>
Vector(const Vector<N>&)

I.e., they're ultimately the same.

One way to differentiate them is to make the template parameter type directly dependent on enable_if's condition:

template <size_t _OtherSize,
    std::enable_if_t<(_Size <= _OtherSize), int> = 0>
    Vector(const Vector<_OtherSize>& v) : Vector()
    {
        std::copy(v.data(), v.data() + _Size, _data);
    }

template <size_t _OtherSize,
    std::enable_if_t<(_OtherSize < _Size), int> = 0>
    Vector(const Vector<_OtherSize>& v) : Vector()
    {
        std::copy(v.data(), v.data() + _OtherSize, _data);
        std::fill(_data + _OtherSize, _data + _Size, 0.0);
    }

As an aside, names like _Size and _OtherSize are reserved for the implementation and thus illegal for user code – lose the underscore and/or the capital letter.

Also, as @StoryTeller hinted at, you don't want the first constructor to apply when _OtherSize == _Size, as the compiler-generated copy constructor has ideal behavior. Said constructor is already less specialized than the copy constructor for same-sized Vectors, so it won't be selected during overload resolution anyway, but it would be best to make the intent clear by switching <= to <.


Don't use names like _Cap; they are reserved for the implementation. In fact, std source uses these names because they are reserved. Do not mimic std/system header internal naming conventions.

template <size_t O>
Vector(const Vector<O>& v) : Vector()
{
  constexpr auto to_copy = (std::min)( O, Size );
  constexpr auto to_fill = Size-to_copy;
  auto const* src=v.data();
  std::copy(src, src + to_copy, _data);
  std::fill(_data + to_copy, _data + to_copy+to_fill, 0.0);
}
Vector(const Vector& v) = default;

you'll find this optimizes down to the code you want; in the no-fill case, std::fill is called with (foo, foo, 0.0), and the body is a loop that is easy to prove is a no-op by a compiler when passed the same pointer twice.