简体   繁体   English

在 c++ 中调用函数并通过 map 传递 arguments?

[英]Calling functions and passing arguments through map in c++?

I've been trying to figure out how I can use std::map to call functions and pass arguments to said functions based on a key.我一直在试图弄清楚如何使用std::map调用函数并基于键将 arguments 传递给所述函数。

I'm translating a project I made in Python to C++, but I've been stuck on this, and I really don't want to resort to a mess of if-else s.我正在将我在 Python 中制作的项目翻译为 C++,但我一直坚持这一点,我真的不想求助于一堆if-else

The way I did that in Python was as so:我在 Python 中这样做的方式是这样的:

return_operation = {  
    "*": Operations.multiply,  
    "^": Operations.exponent,  
    "**": Operations.exponent
    etc...
}

result = return_operation["*"](num_1, num_2)

Is there some sort of way to accomplish this is C++? C++ 是否有某种方法可以做到这一点? I've tried using std::map but I keep getting:我试过使用std::map但我不断得到:

Error C2276 '&': illegal operation on bound member function expression.错误 C2276 '&':对绑定成员 function 表达式的非法操作。

I'm still very new to C++ and I'm totally lost.我对 C++ 还是很陌生,我完全迷路了。

namespace std{
    class Calculator {

    public:
        void multiply(double num_1, double num_2) {
            cout << "MULTIPLYING!" << endl;
            // Normally it would return the result of multiplying the two nums
            // but it only outputs to the console until I can figure this out.
        }

        void initialize() {
            void (Calculator::*funcPtr)();
            funcPtr = &multiply;

            unordered_map<string, Calculator()> operator_function = {
                {"*", &multiply}
            };
        }
    };
}

If you're looking for a straight translation of your python code, then I'd go with something like this:如果您正在寻找 python 代码的直接翻译,那么我会使用以下代码 go :

#include <cmath>
#include <functional>
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<std::string, std::function<double (double, double)>> return_operation{
      { "*", [](double a, double b) { return a * b; } },
      { "^", [](double a, double b) { return std::pow(a, b); } },
    };

    double r = return_operation["*"](5, 3); // r == 15
    std::cout << r << std::endl;
    return 0;
}

From a learning perspective, I totally recommend the answer by Remy Lebeau.从学习的角度来看,我完全推荐 Remy Lebeau 的答案。

First off, you can't add custom types to the std namespace.首先,您不能将自定义类型添加到std命名空间。 Only specializations of existing templates.只有现有模板的特化。

Second, you are using the wrong mapped type for the unordered_map .其次,您为unordered_map使用了错误的映射类型。 Try something more like this instead:尝试更多类似的东西:

class Calculator {
private:
    typedef double (Calculator::*FuncPtr)(double, double);

    unordered_map<string, FuncPtr> operator_function = {
        {"*",  &Calculator::multiply},
        {"^",  &Calculator::exponent},
        {"**", &Calculator::exponent}
        // and so on ...
    };

    double multiply(double num_1, double num_2) {
        cout << "MULTIPLYING!" << endl;
        return num_1 * num_2;
    }

    double exponent(double num_1, double num_2) {
        cout << "EXPONENT!" << endl;
        return pow(num_1, num_2);
    }

public:
    double do_math(string op, double num_1, double num_2) {
        return (this->*operator_function[op])(num_1, num_2);
    }
};

Then, to call a function in the map, you would need to do something like this:然后,要在 map 中调用 function,您需要执行以下操作:

Calculator calc;
...
double result = calc.do_math("*", num_1, num_2);

Online Demo在线演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM