Search code examples
c++c++11c++17function-pointerspointer-to-member

function pointer to overloaded static member - to use as custom deleter in unique_ptr


I have a class with static and overloaded member function. I want to use one them as a custom deleter in a unique_ptr there are lots of questions on this topic, none of them worked for me.

#include <iostream>
#include <memory>
#include <functional>

class A {
    public:
    static void release() {
        std::cout << "void released\n";
    }
    static void release(int*i) {
        std::cout << *i << " released\n";
    }
};

int main()
{
    int i = 10;
    std::unique_ptr<int, decltype(&A::release(int*))> ptr(&i, &A::release); // compiler error
    std::unique_ptr<int, std::function<void(int*)>> ptr(&i, &A::release); // compiler error
    return 0;
}

try it out here: https://onlinegdb.com/H14txk3sL


Solution

  • std::unique_ptr<int, void(*)(int*)> ptr(&i, &A::release); 
    //                   ~~~~~~~~~~~~^
    

    This way, std::unique_ptr's constructor will expect a specific type of a pointer, which will help the compiler resolve ambiguity.


    This:

    decltype(&A::release(int*))
    

    is not a valid syntax. In order yo use decltype(e), you'd have to write decltype(&A::release), but this again would raise an ambiguity error, and so it would have to become:

    decltype(static_cast<void(*)(int*)>(&A::release))
    

    but that's a long-winded way of saying void(*)(int*).


    This:

    std::function<void(int*)>
    

    doesn't help in resolving ambiguity, becuase std::functions's constructor is a template as well, which means the compiler again misses a context that would help it to choose one of the overloaded functions.