Consider the code below:
#include <iostream>
template<typename T> // generic
void f(T)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template<typename T> // overload for pointer types
void f(T*)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
int* p{nullptr};
f(p); // correct delegation to f<T*>();
f(nullptr); // calls f<T>();
}
Live on Coliru
As you can see, calling f(nullptr) results in the generic f(T) being called, and not the pointer overload f(T*). This is quite annoying. I know why this happens: because nullptr is of type std::nullptr_t, and the generic template has a higher overload rank.
How can I "solve" this issue in a straightforward manner? I can of course write two different implementations, one for pointers and one for nullptr_t, then have a generic one that dispatches to one of the two via some SFINAE, but this looks a bit too complicated.
The simplest way would probably be to implement an overload void f(std::nullptr_t), and dispatch to one of the pointer implementations, which can be chosen by you, assuming it does the right thing (whatever the right thing is) for null pointers:
void f(std::nullptr_t) { f(static_cast<void *>(nullptr)); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With