我可以将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上编写的可转换运算符?
答案 0 :(得分:4)
lambda必须指定其返回类型,除非它包含单个return
语句。将来,可以放宽这些规则以允许多个return
语句;但即便如此,它们都必须是相同的类型,因此函数的返回类型是明确的。您的函数返回nullptr_t
或FileInterface*
,具体取决于达到的return
语句。
Lambda语法只允许尾随返回类型,因此您需要:
[](const std::string& filename) -> FileInterface* {
// your code here
}