Передача пользовательского удалителя в std::unique_ptr с помощью объекта std::function

У меня есть следующий рабочий код для инициализации std::unique_ptr с пользовательским удалителем:

class Dataset
{
    ...
private:
    class CustomGDALDatasetDeleter {
    public:
            void operator()(GDALDatasetH res) const {
                ::GDALClose(res);
            }
    };
    using ResourceType = std::unique_ptr<GDALDataset,
                                         CustomGDALDatasetDeleter>;
    ResourceType data;
};

Позже у меня есть этот код:

data = ResourceType(static_cast<GDALDataset*>(::GDALOpen(filename.c_str(),
                                              static_cast<GDALAccess>(mode)))
);

Когда я пытаюсь сделать то же самое с std::function объект и lambdas Я получаю bad_function_call исключение:

class Dataset
{
    ...
private:
    std::function<void (GDALDatasetH)> del = [](GDALDatasetH res){::GDALClose(res);};
    using ResourceType = std::unique_ptr<GDALDataset,
                                         decltype(del)>;
    ResourceType data;

};

Что я здесь не так делаю?

1 ответ

Решение

Вы используете полиморфную функцию-обертку, и при построении по умолчанию она создается пустой.
Таким образом, он вызывает исключение при вызове.

function() noexcept;

template <class A> function(allocator_arg_t, const A& a) noexcept;  

2 постусловия: !*this,

20.9.11.2.4 вызов функции [func.wrap.func.inv]

R operator()(ArgTypes... args) const

1 Эффекты: INVOKE (f, std::forward<ArgTypes>(args)..., R) (20.9.2), где f является целевым объектом (20.9.1) из *this,
2 Возвращает: ничего, если R является void в противном случае возвращаемое значение INVOKE (f, std::forward<ArgTypes>(args)..., R),
3 броска: bad_function_call если !*this; в противном случае - любое исключение, создаваемое завернутым вызываемым объектом.

Установите средство удаления до / во время первого data и все ок.

Другие вопросы по тегам