您可以使用下面的代碼:
#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
之類的東西來刪除某些生物盤。
你想要的「類型nullptr」可能與'static_cast (nullptr)'不同嗎? – Petr
你的第二個選擇看起來像最好的選擇...重載(模板專業化) – basav
你已經在回答問題了......第一和第三選擇或多或少是相同的:你需要一個T *而nullptr不是你不允許的' fct(&a,nullptr)',第二個使用顯式重載來允許它。我無法想象另一個答案... –