Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple custom deleter lambda supplied to std::unique_ptr: why use by-reference capture default ([&]) over no-capture ([])?

Tags:

c++

lambda

Background

Cppreference:s section on std::unique_ptr shows the following demo for supplying a custom deleter to the unique_ptr instance:

std::unique_ptr<D, std::function<void(D*)>> p(new D, [&](D* ptr)
{
    std::cout << "destroying from a custom deleter...\n";
    delete ptr;
});

Where D, for the purpose of this question, is just as simple custom type, say

struct D
{
    D() { std::cout << "D CTOR\n"; }
    ~D() { std::cout << "D DTOR\n"; }
};

Moreover, the reference above states the following type requirement on the deleter:

Type requirements

Deleter must be FunctionObject or lvalue reference to a FunctionObject or lvalue reference to function, callable with an argument of type unique_ptr<T, Deleter>::pointer

...

Member types

pointer: std::remove_reference<Deleter>::type::pointer if that type exists, otherwise T*. Must satisfy NullablePointer.

As a capture list of the deleter lambda in the example above, [&] is used. Based on Cppreference:s section on lambdas, as I see it, the only effect of this capture list in the deleter example above would be to capture the "current object by reference" [emphasis mine]:

[&] captures all automatic variables odr-used in the body of the lambda by reference and current object by reference if exists.

But as I understand it from above, the supplied lambda will be simply called with the object's unique_ptr<T, Deleter>::pointer, no matter if we choose [&] or [] as capture list to the lambda. I don't understand myself why we'd want to use by-reference capture (of the object, which is the unique_ptr instance here?) default here, but I'm pretty sure I'm missing something essential (hence the question).

Question

  • Is there any particular reason to use by-reference capture default ([&]) in the deleter lambda in the example above, as compared to simply using no-capturing ([])?
like image 734
dfrib Avatar asked Feb 14 '17 12:02

dfrib


1 Answers

Here's what the standard says about the deleter of unique_ptr ([unique.ptr.single]/1):

A client-supplied template argument D shall be a function object type (20.9), lvalue-reference to function, or lvalue-reference to function object type for which, given a value d of type D and a value ptr of type unique_ptr::pointer , the expression d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.

Judging by the above, both [] and [&] are perfectly valid.

like image 64
SingerOfTheFall Avatar answered Nov 08 '22 08:11

SingerOfTheFall