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

#c #c 11

#c #c 11

Вопрос:

 error: cannot convert 
'double (Step52::Diffusion::*)(dealii::TimeStepping::ExplicitRungeKutta<dealii::Vector<double> >amp;, dealii::DiscreteTimeamp;)' to 
'double (*)(dealii::TimeStepping::ExplicitRungeKutta<dealii::Vector<double> >amp;, dealii::DiscreteTimeamp;)'
 

Для меня две подписи выглядят одинаково. Кто-нибудь может найти разницу?

Комментарии:

1. одна из них — функция-член

2. Указатели на функции, не являющиеся членами, не совпадают с указателями на функции-члены. Используйте, например static , функции-члены или std::function вместе с лямбдами или аналогичными.

3. @Someprogrammerdude я вижу. Я изменил часть аргумента так, чтобы это было Diffusion::* так. Спасибо.

4. Сообщения об ошибках могут быть трудными для чтения. Ключ здесь находится ближе к началу: (Step52::Diffusion::*) не совпадает с (*) .

Ответ №1:

Вы преобразуете указатель на метод (функцию-член класса) в указатель на глобальную функцию. Они не конвертируются. Либо вам нужно изменить тип указателя назначения, чтобы он совпадал с исходным, либо выполнить следующий обходной путь.

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

Для удобства в следующем коде я также использовал std::function (для сохранения функции) и std::bind (для захвата указателя объекта в качестве первого параметра). Вместо std::bind этого популярно использовать лямбды.

В моем примере я получаю указатель на объект метода C класса f() и проксирую этот указатель как простой (не метод) указатель, который принимается конечной UseFunc() функцией.

Попробуйте онлайн!

 #include <iostream>
#include <functional>

class C {
public:
    int f(int a, bool b) {
        std::cout << int(a   b) << std::endl;
        return a   b;
    }
};

thread_local std::function<int(int, bool)> g_proxy;

int Proxy(int a, bool b) {
    return g_proxy(a, b);
}

void UseFunc(int (* h)(int, bool)) {
    h(3, true);
}

int main() {
    C c;

    g_proxy = std::bind(amp;C::f, amp;c,
        std::placeholders::_1, std::placeholders::_2);

    // Alternatively you can use
    // g_proxy = [amp;](int a, bool b){ return c.f(a, b); };
    
    UseFunc(amp;Proxy);
}
 

Вывод:

 4