Указатель переменной члена

Для данной структуры:

struct foo
{
    void fooFunc(){}
    int fooVar = 0;
};

Я могу создать функцию вызова функции: std::mem_fn( &foo::fooFunc ) так что я могу передать его в другой метод и вызвать его на объекте.
Я хочу знать, есть ли подобная оболочка вызова, но для переменных-членов.

Например, я использую указатель на переменную-член здесь, но я хотел бы использовать упаковщик вызовов:

void bar( std::function< void( foo ) > funcPtr, int foo::* varPtr )
{
    foo myFoo;
    funcPtr( myFoo );
    foo.*varPtr = 13;
}

2 ответа

Решение

NB. Ничего в вашем вопросе не из STL (это библиотека 1990-х годов), std::function а также std::mem_fn являются частью стандартной библиотеки C++, что не одно и то же.

std::mem_fn поддерживает функции-члены и переменные-члены, так что вы можете просто сделать это, чтобы получить доступ к переменной-члену и установить ее:

foo f;
std::function<int&(foo&)> var( std::mem_fn( &foo::fooVar ) );
var(f) = 1;

В дополнение к функциям-членам, std::mem_fn может также обернуть элементы данных и разрешить им доступ для чтения. Итак, следующие работы:

void print_fooVar(foo& f, std::function<int(foo)> varAccess)
{
    std::cout << varAccess(f) << std::endl;
}

foo f;
print_fooVar(f, std::mem_fn(&foo::fooVar)); // prints 0

Как упоминает JonathanWakely в комментариях, вы можете использовать (неуказанный) тип, возвращаемый mem_fn Сам установить данные члена.

foo f;
std::mem_fn(&foo::fooVar)(f) = 13;

Или превратить его в std::function использование

void bar( foo& f, std::function<int&(foo&)> fooVarSet )
{
    fooVarSet(f) = 26;
}

Если все, что вы ищете, это способ генерирования вызываемого объекта для установки fooVar член данных, а не использующий std::mem_fn специально для этого вы можете выполнить работу с помощью лямбда-выражения.

void bar( foo& f, std::function<void(foo)> funcPtr, 
                  std::function<void(foo&, int)> fooVarSet )
{
    funcPtr( f );
    fooVarSet(f, 13);
}

foo f;
bar(f, std::mem_fn(&foo::fooFunc), [](foo& f, int i) {f.fooVar = i;});

Живая демо

Другие вопросы по тегам