I just found out that std::is_pointer_v<nullptr>
translates to false
, thats why the code below:
template <typename T> std::string_view type_str() { /* returns the name of the type */ }
template <typename T> const auto type_name = type_str<T>();
template <typename T> void fptr(const T *const t) {
if (t)
std::print("{} = {:X}.\n", static_cast<const void *const>(t), *t);
else
std::print("nullptr.\n");
}
// #1
template <typename T> requires std::is_pointer_v<T> void f(T t) {
std::print("[{}] is pointer --> ", type_name<T>);
fptr(t);
}
// #2
template <typename T> void f(T t) {
std::print("[{}] is NOT pointer.\n", type_name<T>);
}
int main()
{
const auto v0 = 0xfabada;
auto v1 = 0xc0ffee;
f(&v0);
f(&v1);
f(nullptr);
return 0;
}
Yields the following output:
[const int*] is pointer --> 0xWHATEVER = FABADA.
[int*] is pointer --> 0xWHATEVER = C0FFEE.
[std::nullptr_t] is NOT pointer.
I was expecting std::is_pointer_v<std::nullptr_t>
to yield true
thus calling the #1
function, the only workaround that I've vound so far is to create a kind of typed nullptr
:
template <typename T>
constexpr T *NULLPTR = nullptr;
…
f(&v0);
f(&v1);
f(nullptr);
f(NULLPTR<int>);
…
Which prints:
[const int*] is pointer --> 0xWHATEVER = FABADA.
[int*] is pointer --> 0xWHATEVER = C0FFEE.
[std::nullptr_t] is NOT pointer.
[int*] is pointer --> nullptr.
But I wonder if there is any other way to get a nullptr
which results in std::is_pointer_v
being true
without creating a (template variable) pointer instance which may come with potential missuses. Carrying the pointer type information is a plus.
Sample code here.
But I wonder if there is any other way to get a nullptr which results in std::is_pointer_v being true without creating a (template variable) pointer instance which may come with potential missuses. Carrying the pointer type information is a plus.
Yes there is. Just provide overload of function f
which will handle nullptr
case. You do not need any extra template just add simple function:
void f(std::nullptr_t)
{
std::print("[{}] is nullptr.\n", type_name<std::nullptr_t>);
}