#include <memory>
#include <iostream>
#include <exception>
#include <curl/curl.h>
class client
{
private:
std::unique_ptr<CURL, decltype(&psclient::del_curl)> uptr_curl_;
inline CURL * init_curl()
{
CURLcode result = curl_global_init(CURL_GLOBAL_DEFAULT);
if(result != CURLE_OK)
throw std::logic_error(curl_easy_strerror(result));
return curl_easy_init();
}
inline void del_curl(CURL * ptr_curl)
{
curl_easy_cleanup(ptr_curl);
curl_global_cleanup();
}
public:
inline client()
: uptr_curl_(init_curl(), &client::del_curl)
{
}
}
The compiler keeps complaining No matching constructor for initialization of 'std::unique_ptr<CURL, void (*)(CURL *)>'
It seems to me like the declaration is correct for the deleter template argument. It is a function pointer that returns void and takes a CURL * as an argument. This matches the signature of del_curl
.
Is there yet another random rule, unknown to me, in C++ that specifies a requirement for template arguments to non-static member function pointers? If so, why?
The answer of @R. Sahu is correct imo. However, if you insist of passing a non-static member function deleter, here is a way of doing it using the good old std::bind
and std::function
:
#include <memory>
#include <iostream>
#include <functional>
class Foo
{
private:
std::unique_ptr<int, std::function<void(int*)>> _up;
public:
Foo(): _up(new int[42], std::bind(&Foo::deleter, this, std::placeholders::_1))
{
}
void deleter(int* p)
{
delete[] p;
std::cout << "In deleter" << std::endl;
}
};
int main()
{
Foo foo;
}
PS: I just don't like the bind
, I wonder if one can improve on that.
With a lambda:
Foo(): _up(new int[42],
[this](int* p)->void
{
deleter(p);
}
){}
The second template parameter used in the declaration of uptr_curl_
is void (*)(CURL *)
The type of &client::del_curl
is void (CURL::*)(CURL*)
.
They are not the same. You can change del_curl
to a static
member function. That will resolve the problem.
Update
You can use a non-static
member function with the help of std::function
and std::bind
.
class client
{
public:
client();
private:
std::unique_ptr<CURL, std::function<void(CURL *)>> uptr_curl_;
CURL * init_curl();
void del_curl(CURL * ptr_curl);
};
client::client() : uptr_curl_(init_curl(),
std::bind(&client::del_curl, this, std::placeholders::_1))
{
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With