Please, tell me is it safe to call math functions the following way:
map<string,double(*)<double> func_map = { {"sin", &std::sin } ... }
...
double arg = 2.9;
double res = func_map["sin"](arg);
Please, tell me is it safe to call math functions the following way:
map<string,double(*)<double> func_map = { {"sin", &std::sin } ... }
...
double arg = 2.9;
double res = func_map["sin"](arg);
Taking the addresses of functions in the standard library not on the Designated addressable functions list leads to unspecified behavior (since at least C++20). std::sin
and the other <cmath>
functions are not on that list so, to be safe, wrap them up in functors, like lambdas:
#include <cmath>
#include <map>
#include <string>
int main() {
std::map<std::string, double(*)(double)> func_map = {
{"sin", [](double x) { return std::sin(x); }},
{"cos", [](double x) { return std::cos(x); }},
};
}
is it safe to call math functions the following way:
double res = func_map["sin"](arg);
No, if the function you aim to call is not present in func_map
, using the subscript operator[]
would first insert a double(*)(double)
pointing at nullptr
into the map and then return that nullptr
. Calling nullptr(arg)
would lead to undefined behavior. To make it safe you can do a couple of things:
func_map
const
. This prevents you from using any functions potentially inserting something in the map, like the subscript operator.func_map.at("sin")(arg);
to get an exception (std::out_of_range
) if the function doesn't exist in the map. You can safely catch that and print a message to the user:
try {
double res = func_map.at("sin")(arg);
std::cout << res << '\n';
} catch (const std::out_of_range& ex) {
std::cout << "unknown function\n";
}
find
instead:
if(auto fit = func_map.find("sin"); fit != func_map.end()) {
double res = fit->second(arg);
std::cout << res << '\n';
} else {
std::cout << "unknown function\n";
}