Создайте указатель функции-члена на функцию, которая возвращает std::pair

Я хочу получить доступ к функции, которая возвращает пару через указатель, определенный в соответствии с вводом во время выполнения.

Пример кода:

int main() {
    struct Math::strinfo si; // This was what caused the problem - See answer and question edit

    typedef std::pair<double, string> (*FuncChosen)(struct strinfo *si, double first, double second);
    FuncChosen p = Math::calcSpeed;
}

calcSpeed ​​выглядит так и находится в пространстве имен «Math»:

namespace Math {
    struct strinfo
    {
        string strformula;
        string chosenCalcStr;
    };

    std::pair<double, string> calcSpeed(struct strinfo *si, double distance, double time)
    {
        si->strformula = "Speed = distance / time";
        si->chosenCalcStr = "Speed";
        return make_pair(distance/time, std::to_string(distance) + " / " + std::to_string(time));
    }
}

Я не могу назначить FuncChosen p для calcSpeed, потому что он имеет «lvalue типа std::pair». Приведенный выше код работал нормально, когда calcSpeed ​​возвращал значение типа double. Является ли этот метод несовместимым с функциями, возвращающими пару, и если да, то существуют ли какие-либо обходные пути, не связанные с изменением типа возвращаемого значения функции с пары на что-то другое?

Причина, по которой я хочу назначить указатель во время выполнения, заключается в том, чтобы я мог выбрать, использовать ли calcSpeed ​​или ряд других функций с такими же параметрами и типами возвращаемого значения в соответствии с вводом, и единственный способ сделать это без условных выражений — с помощью этого метода (я считать).

Заранее спасибо,

Изменить: полный код ошибки FYI:

SDT_Test/main.cpp:63:16: Cannot initialize a variable of type 'FuncChosen' (aka 'std::pair<double,   string> (*)(struct strinfo *, double, double)') with an lvalue of type 'std::pair<double, string> (struct strinfo *, double, double)': type mismatch at 1st parameter ('struct strinfo *' (aka 'strinfo *') vs 'struct strinfo *' (aka 'Math::strinfo *'))

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

Я забыл включить строку моего кода, которая выдала бы проблему. Ответ ниже показывает, что проблема была с «struct strinfo *si» в typedef — должно быть «Math::strinfo *si».


person exitcode    schedule 05.11.2014    source источник
comment
Вам не хватает стандартного пространства имен для std::string в паре? Почему бы также не ввести std::pair?   -  person Slava    schedule 05.11.2014
comment
У меня есть «использование std::string» в верхней части программы. Что вы имеете в виду под своим вторым вопросом? Это онлайн-строка в программе, которая возвращает ошибку. Я добавлю полное сообщение об ошибке к вопросу, если это поможет прояснить проблему.   -  person exitcode    schedule 05.11.2014
comment
@exitc0de — проблема и ключ к ответу находятся в сообщении об ошибке. У вас проблема с первым параметром strInfo.   -  person PaulMcKenzie    schedule 05.11.2014
comment
Я имею в виду typedef std::pair<double, string> sometype;, а затем использую sometype   -  person Slava    schedule 05.11.2014
comment
Вау, я не видел "несоответствие типа в 1-м параметре" ('struct strinfo *''. Извините - это была глупая ошибка. Спасибо за вашу помощь - я уточнил в вопросе, но я не видел этого в ошибке до тех пор, пока вы указали на это (Xcode затрудняет чтение полного сообщения об ошибке, и когда мне удалось вставить его, я не прочитал его) Еще раз извините за глупость.   -  person exitcode    schedule 05.11.2014


Ответы (1)


Вы объявляете новый тип с именем strinfo в своем typedef

typedef std::pair<double, string> (*FuncChosen)(struct strinfo *si, double first, double second);
//                                              ^^^^^^^^^^^^^^^^ 
// that's a declaration of new type, not Math::strinfo

Ошибка была бы очевидна, если бы вы опустили ненужное ключевое слово struct в typedef. Измените его на

typedef std::pair<double, std::string> (*FuncChosen)(Math::strinfo *si, double first, double second);

или (ИМХО) более читаемая версия

using FuncChosen = std::pair<double, std::string>(*)(Math::strinfo *si, double first, double second);
person Praetorian    schedule 05.11.2014
comment
Это исправило - обновил вопрос, что я сделал не так и почему я этого не видел. Извините, что пропустил важную часть моей программы перед typedef в main. (см. мое редактирование) - person exitcode; 05.11.2014