Eu tenho um caso em que quero que o parâmetro de função padrão mude quando o tipo de entrada especificou certas características, por exemplo, um objeto pmr tem uma característica de alocador e uma get_allocator
função, então como faço isso? Eu apreciaria uma solução c++ 20 que não envolva SFINAE, a menos que seja impossível, talvez usando if constexpr ou conceitos, não quero escrever duas funções, a menos que seja impossível.
template<typename T>
void new_deleter(T* ptr)
{
delete ptr;
}
template <typename T>
void pmr_deleter(T* ptr)
{
ptr->get_allocator().delete_object(ptr);
}
template<typename T>
using deleter_t = void (*)(T*);
// use pmr_deleter by default when possible
template<typename T>
void delete_object(T* ptr, deleter_t<T> deleter = &new_deleter<T>)
{
deleter(ptr);
}
Editar: graças à resposta descobri o seguinte padrão, que poderia ser facilmente adaptado aos conceitos e ao contexto.
template<typename T>
deleter_t get_default_deleter() {return &new_deleter<T>;}
template<typename T>
deleter_t get_default_deleter()
requires requires (T* ptr) {ptr->get_allocator();}
{
return &pmr_deleter<T>;
}
template<typename T>
void delete_object(T* ptr, deleter_t<T> deleter = get_default_deleter<T>())
{
deleter(ptr);
}
Você pode sobrecarregar as funções e aproveitar o fato de que funções mais restritas serão selecionadas em vez de funções menos restritas.
Não há necessidade de usar duas sobrecargas, você pode simplesmente usar
if constexpr
no corpo da função