Question

I'm having trouble with unique_ptr and a deleter. The following won't compile:

unique_ptr<RSA> rsa(RSA_new(), ::RSA_free);
unique_ptr<RSA> rsa(RSA_new(), ptr_fun(RSA_free));

The compile errors are shown below.

shared_ptr worked fine, but I need to release one of those pointers when assigning it into another structure (and shared_ptr is not amicable).

I'm using GCC 4.7 on Debian 7.3 (x64). Everything is fully patched.

Any ideas what I am doing wrong?


../source/ac-pki.cpp:461:46: error: no matching function for call to ‘std::unique_ptr<rsa_st>::unique_ptr(RSA*, void (&)(RSA*))’
../source/ac-pki.cpp:461:46: note: candidates are:
In file included from /usr/include/c++/4.7/memory:86:0,
                 from /home/jwalton/test/include/ac-common.h:39,
                 from ../source/ac-pki.cpp:1:
/usr/include/c++/4.7/bits/unique_ptr.h:164:2: note: template<class _Up, class> std::unique_ptr::unique_ptr(std::auto_ptr<_Up>&&)
/usr/include/c++/4.7/bits/unique_ptr.h:164:2: note:   template argument deduction/substitution failed:
../source/ac-pki.cpp:461:46: note:   mismatched types ‘std::auto_ptr<_Up>’ and ‘RSA* {aka rsa_st*}’
In file included from /usr/include/c++/4.7/memory:86:0,
                 from /home/jwalton/test/include/ac-common.h:39,
                 from ../source/ac-pki.cpp:1:
/usr/include/c++/4.7/bits/unique_ptr.h:155:2: note: template<class _Up, class _Ep, class> std::unique_ptr::unique_ptr(std::unique_ptr<_Up, _Ep>&&)
/usr/include/c++/4.7/bits/unique_ptr.h:155:2: note:   template argument deduction/substitution failed:
../source/ac-pki.cpp:461:46: note:   mismatched types ‘std::unique_ptr<_Up, _Ep>’ and ‘RSA* {aka rsa_st*}’
In file included from /usr/include/c++/4.7/memory:86:0,
                 from /home/jwalton/test/include/ac-common.h:39,
                 from ../source/ac-pki.cpp:1:
/usr/include/c++/4.7/bits/unique_ptr.h:142:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::unique_ptr<_Tp, _Dp> = std::unique_ptr<rsa_st>]
/usr/include/c++/4.7/bits/unique_ptr.h:142:7: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/4.7/bits/unique_ptr.h:136:17: note: constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr(std::nullptr_t) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::nullptr_t = std::nullptr_t]
/usr/include/c++/4.7/bits/unique_ptr.h:136:17: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/4.7/bits/unique_ptr.h:130:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::remove_reference<_To>::type&&) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::unique_ptr<_Tp, _Dp>::pointer = rsa_st*; typename std::remove_reference<_To>::type = std::default_delete<rsa_st>]
/usr/include/c++/4.7/bits/unique_ptr.h:130:7: note:   no known conversion for argument 2 from ‘void(RSA*) {aka void(rsa_st*)}’ to ‘std::remove_reference<std::default_delete<rsa_st> >::type&& {aka std::default_delete<rsa_st>&&}’
/usr/include/c++/4.7/bits/unique_ptr.h:125:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::conditional<std::is_reference<_Dp>::value, _Dp, const _Dp&>::type) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::unique_ptr<_Tp, _Dp>::pointer = rsa_st*; typename std::conditional<std::is_reference<_Dp>::value, _Dp, const _Dp&>::type = const std::default_delete<rsa_st>&]
/usr/include/c++/4.7/bits/unique_ptr.h:125:7: note:   no known conversion for argument 2 from ‘void(RSA*) {aka void(rsa_st*)}’ to ‘std::conditional<false, std::default_delete<rsa_st>, const std::default_delete<rsa_st>&>::type {aka const std::default_delete<rsa_st>&}’
/usr/include/c++/4.7/bits/unique_ptr.h:120:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::unique_ptr<_Tp, _Dp>::pointer = rsa_st*]
/usr/include/c++/4.7/bits/unique_ptr.h:120:7: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/4.7/bits/unique_ptr.h:114:17: note: constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr() [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>]
/usr/include/c++/4.7/bits/unique_ptr.h:114:17: note:   candidate expects 0 arguments, 2 provided
../source/ac-pki.cpp:550:91: error: cannot convert ‘std::unique_ptr<rsa_st>::pointer {aka rsa_st*}’ to ‘EVP_PKEY* {aka evp_pkey_st*}’ for argument ‘2’ to ‘int PEM_write_PKCS8PrivateKey(FILE*, EVP_PKEY*, const EVP_CIPHER*, char*, int, int (*)(char*, int, int, void*), void*)’
make: *** [source/ac-pki.o] Error 1
Was it helpful?

Solution

You need to give the type of the deleter as well

std::unique_ptr<RSA, void (*)(RSA*)> rsa(RSA_new(), ::RSA_free);

Otherwise, std::unique_ptr uses std::default_delete

OTHER TIPS

The type of the deleter is part of the unique_ptr's type. So change your code to

std::unique_ptr<RSA, decltype(&::RSA_free)> p(RSA_new(), ::RSA_free);

Or, to cut down on the verbosity

using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
RSA_ptr rsa(RSA_new(), ::RSA_free);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top