У меня сложилось впечатление, что я могу использовать 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 );
}
Аналогичная функция существует для переменных-членов. Может быть, вы перепутали это с этим.
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';
std::reference_wrapper
не генерирует функторы. Это только функтор, если оригинальный тип Callable
— std::reference_wrapper::operator()
доступно, только если сохраненная ссылка имеет вызываемый тип.
Непонятно, зачем вам вообще нужен функтор, но если это так, лямбда может быть самым простым решением.
reference_wrapper
вызывается только в том случае, если вызываемый объект является вызываемым. это operator()
просто вызывает указанный вызываемый объект. Если объект, на который ссылаются, не вызывается, то operator()
не существует. В этом смысле он ведет себя как «реальная» ссылка.
refWrap()
будет эквивалентно thirteen()
так плохо сформирован.
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; } );
Таким образом, есть способ сделать это с помощью 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; };