C++17 standard draft
The C++17 n4659 standard draft says:
28.6.1 "Copy":
template<class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last,
                    OutputIterator result);
1 Requires: result shall not be in the range [first, last).
2 Effects: Copies elements in the range [first, last) into the range [result, result + (last -
  first)) starting from first and proceeding to last.
and:
template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2
copy_backward(
    BidirectionalIterator1 first,
    BidirectionalIterator1 last,
    BidirectionalIterator2 result);
17 Requires: result shall not be in the range (first, last].
18 Effects: Copies elements in the range [first, last) into the range [result - (last-first),
  result) starting from last - 1 and proceeding to first. (263) For each positive integer n <= (last -
  first), performs *(result - n) = *(last - n).
The note then explains when to use copy_backward:
263) copy_backward should be used instead of copy when last is in the range [result - (last - first), result)
Therefore, there is no requirement of no overlap for those functions, and unlike for memcpy, the behavior of overlaps is clearly defined in the Effects sections.
You just choose between them because you usually want std::copy for copying left and std::copy_backward for copying right.
C++ also has a ranged version of std::move in <algorithm> which moves instead of copying.