You shouldn't pass builtin types such as integers by constant reference because the copying involved is neligable. Even passing small structs such as a point struct won't really be a problem. Also, you generally pass references and pointers constant when your function is not changing the data the reference or pointer references. It's not so much the space the object itself has but how much time the copy constructor of the object takes. std::string could only consist of a pointer to the null-terminated string but this null-terminated string would have to be allocated memory for and copied inside of std::string's copy constructor.
So can't this be extended to every other function regardless of the parameter type it requires or returns (int, char, string, struct, class, etc...). It seems that this may be beneficial when passing and returning large objects instead of making a copy of them, so why are we applying it to strings if they usually don't take up a lot of space?