【问题标题】:Templating function pointers using Maps使用 Map 模板化函数指针
【发布时间】:2017-07-30 04:03:57
【问题描述】:

我正在尝试使用模板来创建一个映射来理解这些概念,但是我遇到了一个错误并且无法理解我做错了什么。

谁能看看,让我知道我做错了什么?如果可能的话,请分享一个设计的工作示例,我将不胜感激。

谢谢

#include <iostream>
#include <map>

using namespace std;

enum MathOperations
{
    ADD = 0,
    SUBTRACT,
    MULTIPLY,
    DIVISION
};

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

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

template <typename T>
struct MathOp
{
    typedef T (*FuncPtr) (T, T);
};

/* I am getting a warning here, which says variable templates are c++1 extension */
template <typename T>
const std::map<MathOperations, typename MathOp<T>::FuncPtr> MathMap = {
    { MathOperations::ADD, &Addition<T> },
    { MathOperations::SUBTRACT, &Subtraction<T> }
};

int main ()
{
    MathOp<int> mathIntObj;

    /* I am getting error here */
    /* No viable overloaded operator[] for type 'const std::map<MathOperations, typename MathOp<int>::FuncPtr>' */
    std::cout << *(MathMap<int>[MathOperations::ADD])(1, 2) << endl;

    return 0;
}

编辑: 感谢@Piotr Skotnicki,他为我的错误分享了一个解决方案。 我必须进行以下更改:

std::cout << (*MathMap<int>.at(MathOperations::ADD))(1, 2) << endl;

已删除

MathOp<int> mathIntObj;

不过,我需要修复警告。有任何想法吗 ?谢谢

【问题讨论】:

  • 能否复制/粘贴错误信息?那会很有用。
  • map::operator[] 没有 const 重载
  • 这里是错误:没有可行的重载运算符 [] for type 'const std::map::FuncPtr>'sc - 201702190978 谢谢
  • 使用at() 而不是[]
  • 为什么要使用函数指针?为什么不呢? std::function?除了作为FuncPtr 类型别名的持有者之外,MathOp 结构还有什么用处?

标签: c++ function templates stl function-pointers


【解决方案1】:

为什么不使用 lambdas 和类模板std::function,从而大大减少您的代码大小:

#include <iostream>
#include <map>
#include <functional>

using namespace std;

enum MathOperations
{
    ADD = 0,
    SUBSTRACT,
    MULTIPLY,
    DIVISION
};

template <typename T>
const std::map<MathOperations, typename std::function<T(T,T)>> MathMap = {
    { MathOperations::ADD, [](T a, T b){ return a + b; } },
    { MathOperations::SUBSTRACT, [](T a, T b) { return a - b; } }
};

int main ()
{

    std::cout << (MathMap<int>.at(MathOperations::ADD))(3, 2) << endl;
    std::cout << (MathMap<int>.at(MathOperations::SUBSTRACT))(6, 5) << endl;

    return 0;
}

【讨论】:

  • 感谢您分享您的反馈和示例。实际上,我想玩弄函数指针来理解它们。所以我从这个想法开始。我可以知道您在示例中在哪里使用 lambdas 吗?我只看到 std::function。另外,你能告诉我如何解决我用 map 得到的警告吗?谢谢
  • 我在地图的初始化中使用了 lambdas。在您的代码中:按照 Jarod42 的建议将 std::cout &lt;&lt; *(MathMap&lt;int&gt;[MathOperations::ADD])(1, 2) &lt;&lt; endl; 更改为 std::cout &lt;&lt; (MathMap&lt;int&gt;.at(MathOperations::ADD))(1, 2) &lt;&lt; endl; 并踢 MathOp&lt;int&gt; mathIntObj;
  • 明白。我仍然有我在 Map 表达式中提到的警告。有什么想法可以解决吗?谢谢
  • 使用 c++14 或者构建一个定义 [] 运算符的模板包装类 MathMap。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 2014-03-18
  • 2014-09-04
  • 1970-01-01
相关资源
最近更新 更多