A recursive_transform for std::array with various return type
Ensure you pass by const reference consistently
The main problem with your code was that you didn't make the std::array overload take the input by const reference:
auto recursive_transform(std::array&lt;T, S&gt;&amp; input, const F&amp; f)

Just add const! See this Godbolt link with the nested std::arrays working.
Prefer using std::begin() and std::end()
It doesn't really matter if you only want to support containers from the standard library, but when writing templates, prefer using std::begin() and std::end() instead of -&gt;begin() and -&gt;end(). The advantage is that if you are using a non-standard container somewhere that doesn't provide begin() and end() member functions, it will still be possible to overload the out-of-class std::begin() and std::end() functions to add iterator support to that class. If you use it in your algorithm templates, then your algorithms will also support those non-standard classes.