void F(int); // 1: declaration of F(int)
void F(const int); // 2: re-declaration of F(int)
void F(int) { /* ... */ } // 3: definition of F(int)
void F(const int) { /* ... */ } // 4: error: re-definition of F(int)
void F(const int* x); // 1
void F(const int& x); // 2
void F(std::unique_ptr<const int> x); // 3
void F(int* x); // 4
void F(const int x); // 1: declares F(int)
void F(int* const x); // 2: declares F(int*)
void F(const int* const x); // 3: declares F(const int*)
- const type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations
- All of these uses of const are important and not ignored because they are part of the parameter type specification and are not top-level const qualifications that affect the parameter x itself.
- Only top-level, or outermost, const qualifications of the parameter type specification are ignored.
- Never use top-level const on function parameters in declarations that are not definitions (and be careful not to copy/paste a meaningless const). It is meaningless and ignored by the compiler, it is visual noise, and it could mislead readers.
- Do use top-level const on function parameters in definitions at your (or your team’s) discretion. You might follow the same rationale as you would for when to declare a function-local variable const.