Вопрос о функциональных указателях, карте и шаблонах - PullRequest
0 голосов
/ 27 февраля 2019

Я узнаю о функциональных указателях и картах.Мне нужно использовать указатели функций и карты для записи репликации операторов switch без использования if или switch.

Я хочу написать функцию execute (), которая принимает два аргумента "a" и "b" и выполняетоперация с соответствующим символом операции.

#include <iostream>
#include <string>
#include <map>
using namespace std;


// define the function pointer fptr, templated
template <typename T>
using fptr = T(*)(T, T);

template <typename T>
T plus(T a, T b){
    return a + b;
}

template <typename T>
T minus(T a, T b){
    return a - b;
}

template <typename T>
T multiply(T a, T b){
    return a * b;
}

template <typename T>
T divide(T a, T b){
   return a / b
}

// Call back the function pointer on two variables
template <typename T>
T operation(fptr<T> f, T a, T b){
    f(a, b);
}

// Execute map to fit an operation character to an operation function pointer

template <typename T>
T execute(T a, T b, char c){
    std::map<char, fptr<T> > m;
    m['+'] = &plus;
    m['-'] = &minus;
    m['*'] = &multiply;
    m['/'] = &divide;

    return operation(m[c], a, b);
}

int main(){
    execute<int>(1, 2, '+');
    execute<double>(1.2, 3.4, '/');
}

Ниже приведены ошибки, которые я получил.Я не получил опечаток при перезвоне, но ошибки все еще говорят неоднозначно.Интересно, почему это случилось.Я действительно ценю предложения.Большое спасибо!

error: reference to 'plus' is ambiguous
    m['+'] = &plus;
              ^
note: candidate found by name lookup is 'plus'
T plus(T a, T b){
  ^
note: candidate found by name lookup is 'std::__1::plus'
struct _LIBCPP_TEMPLATE_VIS plus : binary_function<_Tp, _Tp, _Tp>
                        ^
error: reference to 'minus' is ambiguous
    m['-'] = &minus;
          ^
note: candidate found by name lookup is 'minus'
T minus(T a, T b){
  ^
note: candidate found by name lookup is 'std::__1::minus'
struct _LIBCPP_TEMPLATE_VIS minus : binary_function<_Tp, _Tp, _Tp>
                        ^

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

1) Вы пропускаете точку с запятой в divide(), а также return в operation() - не так важно, как остальные.

2) Есть причина, по которой using namespace std;нахмурился.Существуют типы функторов шаблонов, называемые std::plus и std::minus, которые сталкиваются с именами.Причина, по которой это не относится к остальным, заключается в том, что у них нет конфликтов имен с вещами в пространстве имен std (то есть они std::multiplies и std::divides).

Я предлагаю вам удалитьusing namespace std; и просто будьте явными, когда вам нужны вещи std, но исправление без этого заключается в использовании &::plus<T>, что означает: получить адрес plus<T>, который находится в глобальном пространстве имен (т.е. не вstd пространство имен).

Также вам не нужно указывать тип для execute(), так как они могут быть выведены из аргументов, которые вы ему задаете (просто убедитесь, что аргументы одного типа).

0 голосов
/ 27 февраля 2019

Это std::plus класс , и вы подняли его до глобального пространства имен, так что оно конфликтует с именем вашей функции.Удалить эту строку:

using namespace std;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...