【问题标题】:Question about function pointers, map and templates关于函数指针、映射和模板的问题
【发布时间】:2019-02-26 23:19:47
【问题描述】:

我正在学习函数指针和映射。我必须使用函数指针和映射来编写 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>
                        ^

【问题讨论】:

  • 试试&amp;plus&lt;T&gt;
  • @jarod42:不幸的是它不起作用:(

标签: c++ dictionary templates


【解决方案1】:

1) 您在divide() 中缺少分号,在operation() 中缺少return - 不如其他重要。

2) using namespace std; 不受欢迎是有原因的。有称为 std::plusstd::minus 的模板函子类型存在名称冲突。其他人不是这种情况的原因是因为它们与 std 命名空间中的内容没有名称冲突(即它们是 std::multipliesstd::divides)。

我建议您删除 using namespace std; 并在您需要 std 内容时明确说明,但不这样做的解决方法是使用 &amp;::plus&lt;T&gt; 这意味着:获取 plus&lt;T&gt; 的地址,该地址位于全局命名空间(即不在 std 命名空间中)。

你也不需要为execute()指定类型,因为它们可以从你给它的参数中推断出来(只要确保参数是相同的类型)。

【讨论】:

    【解决方案2】:

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

    using namespace std;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-04
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 2019-03-23
      • 2021-10-29
      • 1970-01-01
      相关资源
      最近更新 更多