您可以使用以下代码:
#include <type_traits>
template<class T>
void f_impl(T*, T*)
{
std::cout << typeid(T).name() << "\n";
}
template<class T, class U>
void f(T l, U r)
{
static_assert((std::is_same<T, U>::value && std::is_pointer<T>::value) ||
(std::is_same<T, std::nullptr_t>::value && std::is_pointer<U>::value) || // First non-null
(std::is_same<U, std::nullptr_t>::value && std::is_pointer<T>::value) // Second non-null
, "");
using P = typename std::conditional<std::is_same<T, std::nullptr_t>::value, U, T>::type;
f_impl<typename std::remove_pointer<P>::type>(l, r);
}
int main()
{
int i;
f(&i, nullptr);
f(nullptr, &i);
// f(i, nullptr); // won't compile - non-pointer
f(&i, &i);
double d;
// f(&i, &d); // - won't compile
}
此版本测试将允许f
使用一个nullptr
(但不能同时使用两者)或两个指向同一类型的指针进行调用。使用 c++14,您还可以使用std::conditional_t
,std::remove_pointer_t
和std::is_null_pointer
删除一些 biolerplate 之类的东西。