Не могу переместить умный ptr в std :: function - PullRequest
0 голосов
/ 31 января 2020

Я хочу создать std::function, который захватывает auto_ptr/unique_ptr, но не может сделать это должным образом. Мне нужно решение, которое работает на c ++ 11, но я даже не мог понять, как это сделать на c ++ 14

Следующие примеры работают с c ++ 11 (IncByTwenty) abd c + +14 (IncByThirty). Однако, когда я изменяю эти auto s на Func, он больше не компилируется.

typedef std::function<int( int )> Func;
Func IncByTen = std::bind( []( const int& p, int t ) -> int
{
    return p + t;  
}, 10, std::placeholders::_1 );

std::unique_ptr< int > pTwenty(new int(20));
// should have work in c++11 i think? cant assign to Func type
auto IncByTwenty = std::bind( []( const std::unique_ptr< int >& p, int t ) -> int
{
    return ( *p ) + t;  
}, std::move( pTwenty ), std::placeholders::_1 );

std::unique_ptr< int > pThirty = std::make_unique< int >( 30 );
// c++14  cant assign to Func type
auto IncByThirty  = [p{std::move(pThirty) }]( int t ) -> int
{
    return ( *p ) + t;  
};

std::cout << IncByTen(3) << " "  << IncByTwenty(4) << " " << IncByThirty(5);

Я делаю это неправильно? В противном случае мне нужно создать что-то, что можно назначить на std::function, и это должно захватить некоторые локальные переменные, используя оператор перемещения. Есть предложения?

Ответы [ 2 ]

2 голосов
/ 31 января 2020

Невозможно переместить [std::unique_ptr] в std::function

Вы не можете, потому что std::unique_ptr не копируется. (иначе это не могло быть уникальным). std::function требует, чтобы объект функции был копируемым.

Существует предложение добавить оболочку функции для не копируемых (в частности, только для перемещения) функциональных объектов: P0228rX , но такие предложение еще не является частью языка.

2 голосов
/ 31 января 2020

Поскольку std::function является контейнером стирания копируемого типа, он может содержать только копируемые типы.

В документации std::function указано, что это требуется (F является тип, отправленный конструктору):

Требования к типу

Ваша лямбда должна быть копируемой, чтобы содержаться в std::function

Вы можете использовать std::shared_ptr вместо этого или просто использовать не принадлежащий указатель:

auto pThirty = std::make_unique<int>(30);

auto IncByThirty = [p = pThirty.get()](int t) -> int {
    return *p + t;  
};

Однако вы должны убедиться, что указанные данные живут столько же времени, сколько лямбда и все std::function содержащие их.

...