Делегировать параметр 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
и общий шаблон имеет более высокий рейтинг перегрузки.
Как я могу "решить" эту проблему простым способом? Конечно, я могу написать две разные реализации, одну для указателей и одну для nullptr_t
, затем есть общий, который отправляет один из двух через некоторый SFINAE, но это выглядит слишком сложно.
1 ответ
Самый простой способ, вероятно, заключается в реализации перегрузки void f(std::nullptr_t)
и отправьте в одну из реализаций указателя, которую вы можете выбрать, предполагая, что она делает правильные вещи (какими бы правильными они ни были) для нулевых указателей:
void f(std::nullptr_t) { f(static_cast<void *>(nullptr)); }