c++ - 我们可以使用 lambda 创建 unique_ptr 吗?

标签 c++ c++11 lambda

我可以使用 lambda 作为自定义删除器吗?事实上,我使用了一个 C++ 库,其中很多类使用创建/发布 API 来进行实例生命管理(参见下面的示例)

class FileInterface
{
public:
    virtual ~FileInterface() {}

    virtual bool isValid() = 0 ;
    virtual void release() = 0;
};

class RealFile : public FileInterface
{
public:
    static int createFileInterface(const std::string& filename, FileInterface*& pFileInst) 
    {
        try {
            pFileInst = new RealFile(filename);
        } catch (...){
          return -1;
        }   
        return 0;
    }
    virtual bool isValid() { return (m_pFile != NULL);}
    virtual void release() { delete this;}

protected:
    RealFile(const std::string& filename) : m_pFile(NULL) { m_pFile = fopen(filename.c_str(), "wb"); if(m_pFile == NULL) {throw std::runtime_error("error while opening file.");} }
    ~RealFile() {
        std::cout << "DTOR" << std::endl;
        fclose(m_pFile); 
    }
private:
    FILE* m_pFile;
};

所以要使用那种类,我需要自己处理 release(在每次返回、抛出等...)。

FileInterface* pFile = nullptr;
int ret = RealFile::createFileInterface("test.bin", pFile);
std::cout << "isValid = " << pFile->isValid() << std::endl;
pFile->release();

所以我会使用智能指针来处理创建/发布逻辑。我的第一步是处理删除器,它工作正常

auto smartDeleter = [](FileInterface* ptr){ptr->release();};
FileInterface* pFile = nullptr;
int ret = RealFile::createFileInterface("test.bin", pFile);
std::unique_ptr<FileInterface, decltype(smartDeleter)> smartFile(pFile);
std::cout << "isValid = " << smartFile->isValid() << std::endl;

但是在第二步,我为创建逻辑编写了一个 lambda:

auto smartAllocator = [](const std::string& filename){
    FileInterface* pFile = nullptr;
    int ret = RealFile::createFileInterface(filename, pFile);
    if (ret != 0) return nullptr;
    else return pFile;
};

编译器报告错误:

CreateReleasePattern.cpp(65): error C3487: 'FileInterface *': all return expressions in a lambda must have the same type: previously it was 'nullptr'
1>CreateReleasePattern.cpp(65): error C2440: 'return' : cannot convert from 'FileInterface *' to 'nullptr'
1>          nullptr can only be converted to pointer or handle typesCreateReleasePattern.cpp(65): error C3487: 'FileInterface *': all return expressions in a lambda must have the same type: previously it was 'nullptr'
1>CreateReleasePattern.cpp(65): error C2440: 'return' : cannot convert from 'FileInterface *' to 'nullptr'
1>          nullptr can only be converted to pointer or handle types

我该如何解决?有没有我可以在 FileInterface 上编写的可转换运算符?

最佳答案

lambda 必须指定其返回类型,除非它由单个 return 语句组成。将来,这些规则可能会放宽以允许多个 return 语句;但即便如此,它们也必须是同一类型,这样函数的返回类型才能明确。您的函数返回 nullptr_tFileInterface*,具体取决于到达哪个 return 语句。

Lambda 语法只允许尾随返回类型,因此您需要:

[](const std::string& filename) -> FileInterface* {
    // your code here
}

关于c++ - 我们可以使用 lambda 创建 unique_ptr 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18616248/

相关文章:

具有宽松类型要求的 C++17 lambda 捕获

java - WildFly 部署期间出现错误

c++ - 将自身传递给其他类的构造函数的类,两者均使用模板定义

c++ - std::tuple 存储的垃圾值

c++ - 在派生指针上显式调用基类析构函数时编译错误

c++11 - move unique_ptr 后 std::unique_ptr::get 返回的值是否有效?

c++ - 我应该使用从 std::random_device 播种的随机引擎还是每次都使用 std::random_device

c++ - 使用 RecursiveASTVisitor 访问 Clang AST 时确定 Stmt 的父函数节点

c++ - 如果函数在类范围内声明,则 constexpr 不起作用

c++ - 如何在通用 lambda 中完美转发 `auto&&`?