#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)
{
}
}
编译器一直在抱怨No matching constructor for initialization of 'std::unique_ptr<CURL, void (*)(CURL *)>'
在我看来,声明对于deleter模板参数是正确的。它是一个返回void的函数指针,并将CURL *作为参数。这符合del_curl
的签名。
还有另一个随机规则,我不知道,在C ++中指定了对非静态成员函数指针的模板参数的要求吗?如果是这样,为什么?
答案 0 :(得分:7)
@R的答案。 Sahu是正确的imo。但是,如果您坚持传递非静态成员函数删除器,则可以使用旧的std::bind
和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:我只是不喜欢bind
,我想知道是否可以改进。
使用lambda:
Foo(): _up(new int[42],
[this](int* p)->void
{
deleter(p);
}
){}
答案 1 :(得分:2)
uptr_curl_
声明中使用的第二个模板参数是void (*)(CURL *)
&client::del_curl
的类型为void (CURL::*)(CURL*)
。
他们不一样。您可以将del_curl
更改为static
成员函数。这将解决问题。
<强>更新强>
您可以在static
和std::function
的帮助下使用非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))
{
// ...
}