将 nullptr 参数委托给模板代码中的指针重载
Delegate nullptr parameter to the pointer overload in template code
考虑以下代码:
#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>();
}
如您所见,调用 f(nullptr)
会导致调用泛型 f(T)
,而不是指针重载 f(T*)
。这很烦人。我知道为什么会这样:因为 nullptr
是 std::nullptr_t
类型,并且通用模板具有更高的重载等级。
我怎样才能 "solve" 这个问题以直截了当的方式?我当然可以编写两种不同的实现,一种用于指针,一种用于 nullptr_t
,然后有一个通用的实现通过一些 SFINAE 分派到两者之一,但这看起来有点太复杂了。
最简单的方法可能是实现重载 void f(std::nullptr_t)
,并分派到指针实现之一,您可以选择它,假设它做正确的事情(无论正确的事情是什么)对于空指针:
void f(std::nullptr_t) { f(static_cast<void *>(nullptr)); }
考虑以下代码:
#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>();
}
如您所见,调用 f(nullptr)
会导致调用泛型 f(T)
,而不是指针重载 f(T*)
。这很烦人。我知道为什么会这样:因为 nullptr
是 std::nullptr_t
类型,并且通用模板具有更高的重载等级。
我怎样才能 "solve" 这个问题以直截了当的方式?我当然可以编写两种不同的实现,一种用于指针,一种用于 nullptr_t
,然后有一个通用的实现通过一些 SFINAE 分派到两者之一,但这看起来有点太复杂了。
最简单的方法可能是实现重载 void f(std::nullptr_t)
,并分派到指针实现之一,您可以选择它,假设它做正确的事情(无论正确的事情是什么)对于空指针:
void f(std::nullptr_t) { f(static_cast<void *>(nullptr)); }