C ++ Внешняя функция с указателем на функцию в качестве параметра, используется внутри класса с функцией-членом

c++ function-pointers std-function

105 просмотра

2 ответа

Довольно плохо знаком с C ++. Предположим, у меня есть класс:

class A
{
private:
    double m_x, m_y;
public:
    A(double x, double y): m_x {x}
    {
        m_y = extF(m_x, y, *intF);
    }

    double intF(double x) { return 2*x; }
};

И он использует внешнюю глобальную функцию, определенную в другом месте:

double extF(double x, double y, std::function<double(double)> f)
{
    if (x*y < 0)
        return f(x);
    else
        return f(y);
}

Формулы являются поддельными. Это не компилируется. Я пытался просто intF, A::*intF, &A::intF, даже некоторые неортодоксальные комбинации, но это только догадки. Проблема в том, что класс Aне единственный, который использует глобальную внешнюю функцию, и это то, что должно быть в состоянии выбрать пользователь во время выполнения. Поиски выявили некоторые ответы, в которых говорилось, что невозможно создать указатель на функцию-член, подобную этой, потому что она требует инстанцирования (?), Но я не нашел решений. Можно ли это сделать? Если да, то как?


Изменить: Дополнительный вопрос: как сделать указатель на функцию-член, если функция-член const double f(...) const?

Автор: a concerned citizen Источник Размещён: 08.11.2019 11:16

Ответы (2)


3 плюса

Решение

Один вариант просто использовать лямбду:

class A
{
private:
    double m_x, m_y;
public:
    A(double x, double y): m_x {x}
    {
         m_y = extF(m_x, y, [&](double d){ return intF(d);});
    }

    double intF(double x) { return 2*x; }
};

Другой вариант - использовать лямбду и std::mem_fn(пропуская остальной код вашего класса):

A(double x, double y): m_x {x}
{
    auto fn = std::mem_fn(&A::intF);
    m_y = extF(m_x, y, [&](double d) {return fn(this, d);});
}

И, наконец, вы можете избавиться от лямбда-выражений, связав параметр объекта с указателем на функцию-член:

A(double x, double y): m_x {x}
{
    auto fn1 = std::bind(std::mem_fn(&A::intF), this, std::placeholders::_1);
    m_y = extF(m_x, y, fn1);
}

Все это также работает с постоянными функциями-членами.

Автор: Sergey Размещён: 20.08.2016 12:10

2 плюса

Вы можете использовать, std::bindчтобы связать функцию-член.

A(double x, double y): m_x {x}
{
    using namespace std::placeholders;
    m_y = extF(m_x, y, std::bind(&A::intF, this, _1));
}

Или используйте лямбду .

A(double x, double y): m_x {x}
{
    m_y = extF(m_x, y, [this](double d) { return intF(d); });
}

Кстати: он хорошо работает и с функцией-константой, которая здесь не имеет значения.

ЖИТЬ

Автор: songyuanyao Размещён: 20.08.2016 12:10
Вопросы из категории :
32x32