Делегировать параметр 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)); }
Другие вопросы по тегам