In my experience a combination of pass-by-value with move semantics provides good code readability and almost optimal performance in most cases, so that's my default. Unless a profiler disagrees in specific cases, of course.
A map or pretty much any nontrivial data structure is not a flat region.
In any event, waiting to optimize until a profiler tells you to is a reasonable practice as long as you pay attention to scaling. It’s very easy to write, for example, a JSON parser that performs fine in small tests and has a nice small n^2 coefficient. And then someone throws in a bigger input than you tested and your game takes ten minutes to load.
Not necessarily. A hashmap can be implemented in a way it stores both the keys and values in a flat memory region, as long as keys and values are fixed size, and such a structure is way more efficient that traditional array-of-pointers implementation, where fetching each key requires following a pointer and getting the value requires following another pointer.
It’s not just performance. In any moderately complicated C++ program, you will want a function to mutate its argument, and this falls apart.
Sure, you can write in a pure functional style with immutable data structures, but I wish you luck implementing an immutable data structure with asymptotically reasonable performance without using pointers of some sort.