有关函数指针,映射和模板的问题

时间:2019-02-26 23:19:47

标签: c++ dictionary templates

我正在学习函数指针和映射。我必须使用函数指针和映射来编写开关语句的副本,而无需使用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 :(得分:2)

这是一个std::plus class,您已经将它提升为全局名称空间,因此它与您的函数名冲突。删除此行:

using namespace std;

答案 1 :(得分:2)

1)您在divide()中丢失了分号,在return中丢失了operation()-不如其他部分重要。

2)using namespace std;被皱眉是有原因的。有名为std::plusstd::minus的模板函子类型,它们具有名称冲突。其他人之所以不是这样,是因为他们与std命名空间中的东西没有名称冲突(即它们是std::multipliesstd::divides)。

我建议您删除using namespace std;并在需要std时明确声明,但一种解决方法是使用&::plus<T>,这意味着:获取{{ 1}},位于全局名称空间(即不在plus<T>名称空间中)。

此外,您无需指定std的类型,因为可以从您提供的参数中推导它们(只需确保参数是同一类型)即可。