reference_wrapper Ссылочный примитив

У меня сложилось впечатление, что я могу использовать reference_wrapper для генерации функтора, который будет возвращать объект, переданный в ctor reference_wrapper. Но это не работает. Я делаю это неправильно? Если так, есть ли лучший способ сделать это? Я могу написать лямбду, просто кажется, что не должен был.

#include <iostream>
#include <functional>
using namespace std;

void funPtrPrinter( function< int( void ) > output )
{
cout << output() << endl;
}

int main( void )
{
int thirteen = 13;
auto refWrap = ref( thirteen );
funPtrPrinter( refWrap );
}

0

Решение

Аналогичная функция существует для переменных-членов. Может быть, вы перепутали это с этим.

struct foo { int bar; };

Если у вас есть класс с открытыми переменными-членами, вы можете использовать std::mem_fn а также std::bind создать функторы, возвращающие значение переменной.

auto f = std::mem_fn(&foo::bar);
std::cout << f(foo{42}) << '\n';

auto g = std::bind(&foo::bar, foo{42});
std::cout << g() << '\n';
2

Другие решения

std::reference_wrapper не генерирует функторы. Это только функтор, если оригинальный тип Callablestd::reference_wrapper::operator() доступно, только если сохраненная ссылка имеет вызываемый тип.

Непонятно, зачем вам вообще нужен функтор, но если это так, лямбда может быть самым простым решением.

1

reference_wrapper вызывается только в том случае, если вызываемый объект является вызываемым. это operator() просто вызывает указанный вызываемый объект. Если объект, на который ссылаются, не вызывается, то operator() не существует. В этом смысле он ведет себя как «реальная» ссылка.

refWrap() будет эквивалентно thirteen()так плохо сформирован.

0

std::reference_wrapper::operator() участвует в разрешении перегрузки, только если он оборачивает вызываемый объект. int не один, так что то, что вы просите, не сработает.

Вы могли бы сделать это:

int thirteen = 13;
auto refWrap = bind( [&thirteen] { return thirteen; } );
funPtrPrinter( refWrap );

Теперь у вас есть вызываемый, bind выражение, и это может быть вызвано в funPtrPrinter(),

Если бы я был тобой, я бы пропустил посредника и пропустил бы лямбду.

int thirteen = 13;
funPtrPrinter( [&thirteen] { return thirteen; } );
0

Таким образом, есть способ сделать это с помощью std::integral_constant:

const int thirteen = 13;
auto refWrap = bind( &std::integral_constant< int, thirteen >::operator int, std::integral_constant< int, thirteen >() );

Это решает вопрос, но по всем намерениям и целям уступает лямбде:

const int thirteen = 13;
auto refWrap = [=](){ return thirteen; };
0
По вопросам рекламы [email protected]