reference_wrapper Referencing Primitive

别等时光非礼了梦想. 提交于 2019-12-25 08:15:53

问题


I was under the impression that I could use reference_wrapper to generate a functor that would return the object passed into the reference_wrapper ctor. But this isn't working. Am I doing it wrong? If so is there a better way to accomplish this? I can write a lambda, it just seems like I shouldn't have to.

#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 );
}

回答1:


A similar feature exists for member variables. Maybe you confused it with that.

struct foo { int bar; };

If you have a class with public member variables, you can use std::mem_fn and std::bind to create functors returning the value of the variable.

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 doesn't generate functors. It is only a functor if original type is Callable - std::reference_wrapper::operator() is available only if stored reference is of callable type.

It's not clear why you need the functor at all, but if it's the case then lambda might be simplest solution.




回答3:


reference_wrapper is only callable if the object it refers to is callable. Its operator() simply calls the referenced callable object. If the object refered to is not callable then operator() does not exist. In that sense it behaves just like a "real" reference.

refWrap() would be equivalent to thirteen(), so ill formed.




回答4:


std::reference_wrapper::operator() only participates in overload resolution if it's wrapping a callable object. An int isn't one, so what you're asking for won't work.

You could do this:

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

Now you have a callable, the bind expression, and that can be invoked within funPtrPrinter().

If I were you, I'd skip the middleman and pass in a lambda.

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



回答5:


So there is a way to accomplish this using std::integral_constant:

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

This does solve the question, but for all intents and purposes is inferior to the lambda:

const int thirteen = 13;
auto refWrap = [=](){ return thirteen; };


来源:https://stackoverflow.com/questions/22256071/reference-wrapper-referencing-primitive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!