C++: const reference, before vs after type-specifier

eisbaw picture eisbaw · Sep 12, 2010 · Viewed 81k times · Source

What is the difference between the arguments in:

int foo1(const Fred &arg) {
...
}

and

int foo2(Fred const &arg) {
...
}

? I don't see this case covered in the parashift FAQ.

Answer

jamesdlin picture jamesdlin · Sep 12, 2010

Behavior

There is no semantic difference between const T& and T const&; the language treats them as the same type. (The same thing applies to const T* and T const*.)

As a matter of style

Regarding which you should prefer stylistically, however, I'll dissent from a lot of the other answers and prefer const T& (and const T*):

  • const T& is the style used in Stroustrup's The C++ Programming Language book.
  • const T& is the style used in the C++ standard itself.
  • const T* is the style used in K&R's The C Programming Language book.
  • const T* is the style used in the C standard.
  • Due to the above factors, I think const T&/const T* have way more inertia than T const&/T const*. const T&/const T* empirically seem way more common to me than T const&/T const* in all of the C++ and C code that I've seen. I think following common practices is more readable than dogmatically adhering to right-to-left parsing rules.
  • With T const*, it seems easier to misplace the * as T* const (especially if people aren't as accustomed to it). In contrast, const* T is not legal syntax.

What about the right-to-left parsing rule?

Regarding the whole right-to-left parsing argument that people seem to love to use: as I mentioned in a comment to another answer, const T& reads fine right-to-left too. It's a reference to a T constant. "T" and "constant" each can work as an adjective or a noun. (Additionally, reading T const* right-to-left can be ambiguous since it could be incorrectly interpreted as "pointer constant to T" instead of as "pointer to constant T".)