Garmaine Staff asked 2 years ago

I ran clang-tidy (the "modernize" modules) on a project tree that I have been trying to keep reasonably up to date with C++17. Almost everything it corrected was unsurprising to me, except for one thing: It changed all of these types of constructs:

void foo(const std::string& str) {

.. to this:

void foo(std::string str) {

And I don't understand why. To my untrained eye this would mean two things:

  1. It would need to copy the object rather than just pass a reference. (Though I assume there are situations when the compiler can deduce that it can just pass a pointer when it generates the code — but the reference makes it explicit (which is better imho)).
  2. The const is there to tell the function body developer that it shouldn't be changing the input string, and that if it needs to modify the string it needs to store its own copy somewhere.

I do see an upside though — by just passing an object as a const reference it's a mere "remove const" cast away from being changed anyway, so I guess passing by value would solve that.

Why does it recommend removing const references with non-const pass-by-values?