размер объекта std :: unique_ptr с пользовательским удалителем (лямбда с захватом by-ref) - PullRequest
0 голосов
/ 11 ноября 2019

В следующем коде у меня есть пользовательское средство удаления (использующее лямбду, которое захватывает по ссылке) для std::unique_ptr. Я ожидал, что размер объекта std::unique_ptr должен быть таким же, как и для удаления по умолчанию (т. Е. С использованием оператора delete), поскольку захват выполняется по ссылке. Я понимаю, что функторы без состояния и лямбды (без перехвата) не несут взыскания по размеру, тогда почему перехват по лямбда-ссылкам влечет за собой размер? Заранее благодарим за объяснение.

#include <iostream>
#include <memory>

class X{};

int main()
{
    // custom deleter using a state-full lambda
    double data[100]{0};
    auto lmb_sf = [&data](X* ptr){
        // do something
        std::cout<<"In custom deleter using a state-full lambda\n";
        delete ptr;
    };

    std::unique_ptr<X,decltype(lmb_sf)> ptr_sf(new X, lmb_sf);
    std::cout<<"Size of ptr_sf = "<<sizeof(decltype(ptr_sf))<<"\n";

    return 0;
}

Выходной захват по ссылке (т. Е. С ... lmb_sf = [& data] ...)

Size of ptr_sf = 16
In custom deleter using a state-full lambda

Выходной захват по значению (то есть с ... lmb_sf = [data] ...)

Size of ptr_sf = 808
In custom deleter using a state-full lambda

Ответы [ 2 ]

5 голосов
/ 11 ноября 2019

Я понимаю, что функторы без состояния и лямбды (без захвата) не несут штрафов за размер

Действительно.

тогда почему лямбдызахват ссылки повлечет за собой размер штрафа?

Поскольку лямбда-захват захватывает. Это состояние должно храниться где-то.

4 голосов
/ 11 ноября 2019

Лямбда, которая захватывает ссылку, должна внутренне хранить ссылку.

Хотя я не думаю, что размер лямбда-объекта определяется стандартом, он должен по крайней мере логически содержать адрес объектазахватил.

...