C++ tidbit #9: nullptr_t doesn't behave like a pointer type?

C++ tidbit #9: nullptr_t doesn't behave like a pointer type?

Suppose you want to customize some behavior for compile-time nullptrs. As a concrete example let's take a comparison of pointers :


struct C {
? ? void* m_p;

? ? bool operator==(int* p) const { return m_p == p;}
? ? bool operator==(const int* p) const { return m_p == p;}
...        

is fine, but -



...
  bool operator==(nullptr_t) const { return false;}
  bool operator==(const nullptr_t) const { return false;}
};        

gives a redefinition error (on clang: "member function already defined or declared").

Why?

Answer, Part 1

`nullptr_t` is defined as the typedef :


using?nullptr_t?=?decltype(nullptr);        

So `nullptr_t` should be interpreted as 'pointer to null' and `const nullptr_t` should be interpreted as 'const pointer to null'.

Therefore, the right analogue to `const nullptr_t` is not `const int*`, but rather `int* const`. I remember an advice I got somewhere about interpreting pointer types in C/C++: read them from right to left. Thus, `int* const` should be interpreted as 'const pointer to int', and `const int*` as 'pointer to const int' (stretching that old advice a bit).

Armed with this insight we can reduce the original conundrum to a version with no nullptr_t:



void f(int* ) {}
void f(int const* ) {} // fine,
void f(int* const ) {} // redefinition error??        

Answer, Part 2

Top level const does not impact function signature!

Here's some SO discussion that I won't repeat - suffice to say I don't find any of the mentioned reasons compelling. Personally, I consider it as just an old design decision.

So bottom line, `f(int*)` and `f(int* const)` are indistinguishable - as are `f(nullptr_t)` and `f(const nullptr_t)`.

yep - top level const does not make any diff for func decl, and tidy will complain.

Ayal Hitron

Believer in democracy

2 年

"f(int)" and "f(const int)" are the same signature per the standard, they are completely equivalent (hence the "const" is redundant). https://godbolt.org/z/7vd6PTvz7 This makes sense to me, since this "const" is just an implementation detail.

David Amar

Opinions are my own. Team lead at InnerEye

2 年

Nice! I did not know that it can not differentiate between them. What was the use case that made you look into it?

回复

要查看或添加评论,请登录

社区洞察

其他会员也浏览了