Variable templated default function parameter

I have a case where i want the default function parameter to change when the input type has specified certain traits, for example a pmr object has an allocator trait, and get_allocator function, so how do i do that ? I would appreciate a c++20 solution that doesn’t involve SFINAE unless otherwise impossible maybe using if constexpr or concepts, i don’t want to write two functions unless otherwise impossible.

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);
}

>Solution :

You can overload the functions and use the fact that more constrained functions will be selected over less constrained functions.

// Default delete
template<typename T>
void delete_object(T* ptr) {
    delete ptr;
}

// This will be selected if ptr->get_allocator().delete_object(ptr) is well formed
template<typename T>
void delete_object(T* ptr) 
    requires requires { ptr->get_allocator().delete_object(ptr); } 
{
    ptr->get_allocator().delete_object(ptr);
}

// Or explicitly specify the deleter if necessary
template<typename T>
using deleter_t = void (*)(T*);

template<typename T>
void delete_object(T* ptr, deleter_t<T> deleter) {
    deleter(ptr);
}

Leave a Reply