When using the fftw3 fast fourier transform (FFT) library, a plan variable is declared and initialised, it is then used to perform some FFTs and subsequently destroyed when the memory is to be freed:
#include <fftw3.h>
// Declare plan
fftw_plan myPlan;
// Initialise plan
myPlan = fftw_plan_dft_r2c(3, m, f, reinterpret_cast<fftw_complex*>(fk.get()), FFTW_PATIENT);
// Perform an FFT
fftw_execute(myPlan);
// Free the memory associated with the plan
fftw_destroy_plan(myPlan);
In the above: m, f and fk.get() are raw pointers to arrays and the code runs perfectly well.
However, I've been attempting to set up this process using a smart pointer that will automatically free the memory when the plan goes out of scope. This is what I have come up with:
std::unique_ptr<fftw_plan, decltype(&fftw_destroy_plan)> myPlan(
fftw_plan_dft_r2c(3, m, f, reinterpret_cast<fftw_complex*>(fk.get()), FFTW_PATIENT),
fftw_destroy_plan
);
Unfortunately, I get the following compiler error:
no instance of constructor "std::unique_ptr<_Tp, _Dp>::unique_ptr [with _Tp=fftw_plan, _Dp=void (*)(fftw_plan p)]" matches the argument listC/C++(289)
strFunc.cc(26, 9): argument types are: (fftw_plan, void (fftw_plan p))
I can see that the types of the second arguments don't match, but dereferencing doesn't seem to fix the issue (and I don't see why it would).
If anyone has some insights as to how to progress, I would greatly appreciate it!
Thanks!
If I understand the documentation correctly, then fftw_plan
is an opaque pointer type.
In that case you can do:
struct deleter {
// this alias is important for unique_ptr
using pointer = fftw_plan;
void operator()(pointer plan) const { fftw_destroy_plan(plan); }
};
std::unique_ptr<void, deleter> myPlan(fftw_plan_dft_r2c(/*...*/));
The important part here is that pointer
must be a type that behaves like a pointer with respect to nullptr
. That means there is an empty state that compares equal to nullptr
(while others don't) and can be assigned/constructed from nullptr
. unique_ptr
needs this state for an empty or moved-from instance.