【问题标题】:Elegant way to defining the various operations and costants定义各种操作和常量的优雅方式
【发布时间】:2021-06-25 10:50:25
【问题描述】:

我正在创建一个 C++ wxWidgets 计算器应用程序。我需要一种方法来轻松定义程序中可用的各种操作和成本。 现在,在我的主框架类中,我私下声明了这些数组:

const wxString ops[5] = //operations that require a number before and after
{
    L"+", 
    L"-", 
    L"\u00D7", //multiplication
    L"\u00F7", //division
    L"^"
};  
const wxString extra[10] = //operations that only require a number after (don't know the right name for this)
{
    L"\u221A", //square root
    L"sin", 
    L"cos", 
    L"tan", 
    L"arcsin", 
    L"arccos", 
    L"arctan"
};  
const wxString consts[2] = //constants
{
    L"\u03C0" //pi
};

我使用 wxString 是因为在解析方程的函数中,它会检查是否找到其中之一,获取对应的数组索引并在切换到实际计算时使用它。

例如,如果我键入sin45+5,解析器会找到sin,检查它是否属于opsextraconsts 数组,然后循环遍历extra 数组并得到它它的索引是 1,因为它是数组中的第二个元素。然后我有这段代码,它返回了 sin 操作的结果:

        switch (GetExtraId(op)) { default: return 0;
            case 0: return sqrt(b); //radice quadrata
            case 1: return sin(b * 3.14159265359 / 180); //trasformazione da radianti a gradi
            case 2: return cos(b * 3.14159265359 / 180);
            case 3: return tan(b * 3.14159265359 / 180);
            case 4: return asin(b) * 180 / 3.14159265359; 
            case 5: return acos(b) * 180 / 3.14159265359;
            case 6: return atan(b) * 180 / 3.14159265359;
        }

我在问:有没有更优雅的方式来做到这一点?如果我想为 + 操作创建一个按钮,我必须将其标签设置为ops[0],这有点不方便。我试过类似的东西:

enum class ops : wxString
{
    add = L"+",
    sub = L"-",
    mul = L"\u00D7",
    div = L"\u00F7",
    pow = L"^"
};

但是我必须以某种方式将它们转换为int 才能在交换机中使用它们。另外,我不能在枚举中使用 wxString,因为它不是整数类型。

【问题讨论】:

  • 您可能想要这些名称:二元运算符/一元运算符。

标签: c++ class enums calculator wxwidgets


【解决方案1】:

似乎是map 使用的经典案例。你可以看看这个:

std::map<std::string, std::function<double(double, double)> ops;

然后填充它:

double add(double, double);
ops.insert({"+", add}); // Maps "+" to the pointer to add()
ops.emplace("-", subtract); // Or even like so

那么,你可以直接从map调用返回:

ops["+"](3.14, 1.61); // Returns 4.75

这样你可以直接查询函数,不需要字符串到整数的映射,然后基于这个整数switch

至于与 wxString 一起使用,您可能需要查看此list of conversions

【讨论】:

  • 甚至ops.emplace("+", add);
  • 如果我尝试写 std::map &lt; wxString, function&lt;long double(long double, long double)&gt; &gt; binary; 我得到 E0864 function is not a model 。
  • @iKebab897 你能利用these 转换并将一些可转换类型映射到std::map>
  • 它必须是 wxString 因为它支持 Unicode 字符。无论如何,问题似乎是“功能”这个词,如MSVS2019 underlines it in red.
猜你喜欢
  • 2019-05-01
  • 2011-06-05
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-10
  • 2013-04-01
  • 2010-09-07
相关资源
最近更新 更多