Используя указатель this внутри прототипа std :: function

насколько я понимаю, функция-член отличается от нормальной функции, потому что есть дополнительный параметр указателя this.

Итак, моя идея состоит в том, чтобы сделать следующую функцию шаблона члена для одного из моих классов:

template <class T>
void    ApplyFunction(function<void(vector<int>&, T)> fun, T val);

а затем я буду использовать его внутри одного из моих классов, например:

Thing.ApplyFunction(myMethod, this);

а Thing будет использовать myMethod из моего текущего экземпляра класса.


По большей части этот код является предположением, поэтому я хотел бы пояснить, сработает ли это. Также не уверен, в каком направлении это:

void    ApplyFunction(function<void(vector<int>&, T)> fun, T val);

или же

void    ApplyFunction(T val, function<void(vector<int>&, T)> fun);

Пример кода, описывающий, почему мне может понадобиться что-то вроде этого:

void    ClassA::callbackMethod(vector<int> &array)
{
        //I can edit the array here
}

void    ClassA::someMethod(void)
{
    ClassB B;

    B.ApplyFunction(callbackMethod, this);

    //now whenever B wants to edit the array, it can by using callbackMethod

    B.ComplicatedStuff(); // B uses the callbackMethod multiple times here
}

Что именно вы пытаетесь решить? this->myMethod(args) должен работать нормально (вероятно, myMethod(args) тоже).

Stephen Newell 22.03.2018 07:18

класс, к которому принадлежит Thing, будет использовать функцию-член какого-либо другого класса в качестве аргумента указателя функции.

Theo Walton 22.03.2018 07:21

std :: function - это шаблон класса, концептуально не имеющий ничего общего с указателем на член.

llllllllll 22.03.2018 07:26

Какая польза от вызова B.ApplyFunction перед вызовом B.ComplicatedStuff? Почему бы не передать функцию напрямую в B.ComplicatedStuff?

Stephen Newell 22.03.2018 07:35

возможно, есть B.ComplicatedStuff и B.ComplicatederStuff, но все равно это сводится к одному и тому же вопросу

Theo Walton 22.03.2018 07:37

Вы ищете std::invoke

Passer By 22.03.2018 07:46

@PasserBy не могли бы вы подробнее рассказать, как я бы использовал его для достижения аналогичных результатов

Theo Walton 22.03.2018 07:55

@PasserBy это C++ 17

Swift - Friday Pie 22.03.2018 10:10

@TheoWalton std::invoke(classmemberponter, classinstance, arguments... ) передаст указатель на classinstance как this на memberpointer. Но я думаю, что хранение лямбда может быть более прозрачным ... у обоих есть проблема с жизнью объекта

Swift - Friday Pie 22.03.2018 10:26

Что делает ApplyFunction?

Yakk - Adam Nevraumont 22.03.2018 16:25

@Yakk Я хочу, чтобы он вызывал функцию один раз, а затем сохранял ее, чтобы ее можно было вызывать в другой раз

Theo Walton 23.03.2018 00:26

@theo как вы собираетесь хранить T? Вам нужна буква T, кроме как для вызова функции?

Yakk - Adam Nevraumont 23.03.2018 01:10
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
12
97
1

Ответы 1

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

template <class T>
void ApplyFunction(T&& func) {
    func(/*pass in your vector here*/);
}

После этого вы можете вызвать его из A, передав лямбду.

void    ClassA::someMethod(void)
{
    ClassB B;
    B.ApplyFunction([&](std::vector<int>& vec){
        // do stuff with vec here
        // or call a member function
        callbackMethod(vec);
        vec.push_back(2);
    });
}

Это будет быстрее, поскольку передача такого параметра шаблона почти не требует дополнительных затрат при обычном вызове функции. Если функция является встроенной, это может быть так же дешево, как простой вызов функции-члена.

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

Редактировать

Если вы хотите сохранить функцию, вам не нужен шаблон, вы можете просто взять std::function в качестве параметра в ApplyFunction.

void ApplyFunction(std::function<void(std::vector<int>&)> func) {
    //Store it, call it now or call it later.
    m_func = func;
    m_func(/*pass in your vector here*/);
}

Назовите это так же, с лямбдой. Использование такой лямбды является предпочтительным методом при привязке функции-члена к экземпляру. Вместо того, чтобы передавать this отдельно, лучше обернуть его лямбдой и получить так сказать бесплатно.

проголосовали за, но, к сожалению, я хотел бы сохранить функцию внутри класса B - так что не выдержите принятия. Спасибо хоть

Theo Walton 22.03.2018 09:46

@TheoWalton, я вижу, добавил обновление, чтобы показать, как вы это сделаете.

super 22.03.2018 10:16

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