【问题标题】:How to use lambdas and functions as custom deleters for unique_ptr如何使用 lambdas 和函数作为 unique_ptr 的自定义删除器
【发布时间】:2017-06-01 21:15:53
【问题描述】:

我正在测试 unique_ptr 的自定义删除器。 奇怪的是,只有作为函数对象的删除器才能正常工作。 如果我用函数或 lambda 替换它们,程序将无法编译。 我做错了什么?

这是我完整的测试程序

#include <iostream>
#include <memory>

using namespace std;


class Vehicle {
public:
    Vehicle(){ cout<<"Vehicle constructor..."<<endl;}
    virtual ~Vehicle(){cout<<"~Vehicle destructor..."<<endl;}
    virtual void go()=0;
};

class Car:public Vehicle {
    public:
    void go() override {
        cout<<"Going by car..."<<endl;
    }
};

class Bicycle:public Vehicle {
    public:
    void go() override {
        cout<<"Going by bicycle..."<<endl;
    }
};

// Custom deleters
auto CustomLambdaDeleter = [](Vehicle* v){
    cout<<"Custom lambda deleter called..."<<endl;
    delete v;
};

void CustomFunctionDeleter(Vehicle* v){
    cout<<"Custom function deleter called..."<<endl;
    delete v;
}

struct CustomFunctorDeleter
{
    void operator()(Vehicle* v ) const {
        cout<<"Custom functor deleter called..."<<endl;
        delete v;
    }
};


// Doesn't compile
//using VehiclePtr = unique_ptr<Vehicle, decltype(CustomLambdaDeleter)>;
// Doesn't compile
//using VehiclePtr = unique_ptr<Vehicle, decltype(&CustomFunctionDeleter)>;
// Works ok
using VehiclePtr = unique_ptr<Vehicle, CustomFunctorDeleter>;


class VehicleFactory {
public:
    static VehiclePtr createVehicle(string type){
        VehiclePtr vptr;
        if("bicycle"==type) {
            vptr.reset(new Bicycle());
            // This also works
            // vptr= (VehiclePtr) new Bicycle();
            return vptr;
        }
        else if("car"==type) {

           vptr.reset( new Car());
           return vptr;
        }

        return nullptr;
    }
};


void vehicleFactoryTest(){
    cout<<"* Starting vehicleFactoryTest()..."<<endl;
    auto firstVehicle = VehicleFactory::createVehicle("bicycle");
    firstVehicle->go();
    auto newCar = VehicleFactory::createVehicle("car");
    newCar->go();
}

int main(int, char **)
{

    vehicleFactoryTest();
    return 0;
}

【问题讨论】:

  • 为了帮助人们回答您的问题,您需要更具体地说明错误。请edit 您的帖子包含您从minimal reproducible example 获得的确切错误(最好使用复制+粘贴以避免转录错误)。
  • 我收到以下错误:使用已删除的函数 '::()'

标签: c++ c++11 lambda unique-ptr


【解决方案1】:

问题不在于任何一个

using VehiclePtr = unique_ptr<Vehicle, decltype(CustomLambdaDeleter)>;

using VehiclePtr = unique_ptr<Vehicle, CustomFunctorDeleter>;

这两个是自己编译的。问题在于createVehicle中的以下行

VehiclePtr vptr;

这里,您默认构造一个unique_ptr,它不会在使用 lambda 删除器的情况下编译,因为 lambda 不是默认可构造的。所以你需要

VehiclePtr vptr{nullptr, CustomLambdaDeleter};

在您使用函数指针的情况下,您尝试使用nullptr 删除器默认构造unique_ptr,这是不允许的。修复方法类似,在这种情况下您需要将指针传递给函数。

VehiclePtr vptr{nullptr, CustomFunctionDeleter};

您在createVehicle 的最终返回语句中也犯了类似的错误。将该行更改为

return vptr;

【讨论】:

  • @Fedorov7890 已更新,您的退货声明中还有另一个错误。如果仍有问题,请使用在线编译器并粘贴指向无法编译的示例的链接。
  • 谢谢,从 'return nullptr' 到 'return vptr' 的改变解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-10
  • 2015-08-13
  • 1970-01-01
  • 2015-08-15
  • 2023-03-11
  • 2013-03-30
  • 1970-01-01
相关资源
最近更新 更多