如何避免多个删除lambda?

时间:2017-01-23 20:09:55

标签: c++ lambda

如何使用以下内容避免多个删除lambda:

class A {};
class B : public A {};

auto del = [](A *p) { delete static_cast<A*>(p); }
std::vector<std::unique_ptr<A, void (*)(A*)>> vec;

vec.emplace_back(new B, del); //[1]
/* OR */
vec.emplace_back(new B, [](A *p) { delete static_cast<B*>(p); }); //[2]

因此,继承B的班级A会被放入std::vector std::unique_ptr<A>个{@ 1}}并使用自定义删除工具来正确调用B的析构函数。删除器是一个lambda,据我所知这样做:

auto l1 = []{};
auto l2 = []{};

将产生两个单独的类型,即使lambda是相同的,因为lambdas是内部的匿名struct。上面的向量元素(unique_ptr s)是否有办法仅对所有这些元素使用一个 lambda删除器?也许通过预先声明并将其传递给{1}},如[1]中所述?或者它与给予&#34; new&#34;几乎相同lambda用于[2]中的每个这样的调用?

2 个答案:

答案 0 :(得分:3)

好吧,为了避免在[2]中创建很多lambdas(可能无论如何都会被优化掉),[1]是一个很好的方法,尽管每次添加新对象时都会复制lambda实例(可能也已经优化了,但我不确定)。

但是,如果你不想在每次添加std::unique_ptr时处理传递删除器的麻烦,那就做一个仿函数:

struct deleter {
    void operator()(A *p) const noexcept { delete static_cast<B*(p); }
};

因为deleter是DefaultConstructible,std::unique_ptr的构造函数可以自己创建一个删除对象,而不必传递一个。使用lambdas是不可能的,因为它们不是DefaultConstructible。

答案 1 :(得分:1)

构造函数将删除器复制到每个unique_ptr。使用lambda做什么并不重要,每个unique_ptr对象都会有一个副本。

另外,我建议不要将删除器的类型作为函数指针。而是使用lambda的decltype来避免间接调用。会为你节省一些性能。此外,非捕获lambda可能会为unique_ptr占用0个字节的存储空间,而函数指针将为您拥有的每个sizeof(void*)占用unique_ptr