(我已经阅读了C++中lambda派生的隐式仿函数的生命周期是什么?已经没有回答这个问题了.)
我理解C++ lambda语法只是用于创建具有调用操作符和某个状态的匿名类的实例的糖,并且我理解该状态的生存期要求(由您是否通过引用的值捕获来决定.)但是什么是lambda对象本身的生命周期?在以下示例中,std::function返回的实例是否有用?
std::function<int(int)> meta_add(int x) {
auto add = [x](int y) { return x + y; };
return add;
}
Run Code Online (Sandbox Code Playgroud)
如果是,它是如何工作的?这对我来说似乎有点太神奇了 - 我只能通过std::function复制整个实例来实现它的工作,根据我捕获的内容,这可能非常繁重 - 过去我std::function主要使用裸函数指针,复制它们是快.鉴于std::function类型擦除,它似乎也有问题.
我在论坛上听到使用std::function<>原因性能下降.这是真的吗?如果是真的,这是一个很大的性能下降?
Bjarne Stroustrup在他的C++ Style and Technique FAQ中写道,强调我的:
因为C++支持几乎总是更好的替代方案:"资源获取是初始化"技术(TC++ PL3第14.4节).基本思想是通过本地对象表示资源,以便本地对象的析构函数将释放资源.这样,程序员就不会忘记释放资源.例如:
Run Code Online (Sandbox Code Playgroud)class File_handle { FILE* p; public: File_handle(const char* n, const char* a) { p = fopen(n,a); if (p==0) throw Open_error(errno); } File_handle(FILE* pp) { p = pp; if (p==0) throw Open_error(errno); } ~File_handle() { fclose(p); } operator FILE*() { return p; } // ... }; void f(const char* fn) { File_handle f(fn,"rw"); // open fn for reading and writing // use file through f }在系统中,我们需要为每个资源提供"资源句柄"类.但是,我们不必为每次获取资源都有一个"finally"子句.在现实系统中,资源获取比资源种类多得多,因此"资源获取是初始化"技术导致的代码少于使用"最终"构造的代码.
请注意,Bjarne写的"几乎总是更好"而不是"总是更好".现在我的问题是:finally …
我正在使用C++与OpenCV库,这是一个库图像处理,虽然这与这个问题无关.目前我有一个设计决定.
作为C库的OpenCV将其数据结构(例如CvMat)声明为结构体.要创建它们,可以使用cvCreateMat之类的函数,要释放它们,可以使用cvReleaseMat等函数.作为一名C++程序员,我创建了一个特殊的cv_scoped类,当它超出范围时会自动调用cvReleaseMat(如boost::scoped_ptr).
什么我现在意识到的是,我希望我可以使用auto_ptr,并shared_ptr在案件.我只是觉得为自己cv_auto_ptr和cv_shared_ptr类编写代码是个坏主意,更不用说浪费时间了.所以我一直在寻找解决方案,我想出了三种可能性.
首先,我可以使用我已经制作的cv_scoped类.我将它重命名为cv_ptr然后使用智能指针:std::auto_ptr<cv_ptr>.关于这个令人讨厌的事情是,我总是要两次取消引用:
std::auto_ptr<cv_ptr> matrix(cv_ptr(cvCreateMat(320, 240, CV_32FC3)));
cvPow(matrix.get()->get()); // one get for the auto_ptr, one for the cv_ptr
Run Code Online (Sandbox Code Playgroud)
我知道看起来我可以声明一个隐式转换,但实际上我无法实现 - 大多数OpenCV的函数都有参数void* - 因此不会调用隐式转换.我真的想要一种这样做的方式,我不必进行双重引用.
其次,我可以以某种方式覆盖operator delete.我不想覆盖全局运算符delete,因为我只想将它应用于CvMat(和其他一些)类型.但是,我无法更改库,因此无法添加operator delete到CvMat结构中.所以我不知道这是怎么回事.
第三,我可以只重写我自己auto_ptr,scoped_ptr和shared_ptr.他们不是大班,所以不会太难,但我觉得这是糟糕的设计.如果我这样做,我可能会做这样的事情:
class cv_auto_ptr {
public:
cv_auto_ptr();
~cv_auto_ptr();
// each method would just be a proxy for the smart pointer
CvMat* get() { return this->matrix_.get()->get(); …Run Code Online (Sandbox Code Playgroud)