我被要求通过功能表使用std::function
来实现桌面计算器,仅适用于二进制运算符。所以我有这段代码:
#include <functional>
#include <iostream>
#include <string>
int main()
{
std::map<std::string, std::function<int(int, int)>> binOp;
binOp["+"] = [](int a, int b){return a + b;};
binOp["*"] = [](int a, int b){return a * b;};
binOp["-"] = [](int a, int b){return a - b;};
binOp["/"] = [](int a, int b){return a / b;};
binOp["%"] = [](int a, int b){return a % b;};
for(const auto& p : binOp)
std::cout << 9 << " " << p.first << " " << 8 << " = " << p.second(9, 8) << std::endl;
}
*对于整数操作数的二进制运算符,该程序运行正常。我想让我的类模板通用,以处理不同类型的操作数int, double, std::string...
,因此我在decltype
的帮助下独自尝试了此操作:
template <typename T>
struct BinOp
{
BinOp() = default;
BinOp(T f) : fn(f){}
std::function<T> fn;
using arg_type = decltype(fn(0, 0));
arg_type operator()(arg_type a, arg_type b){return fn(a, b);}
};
int main()
{
std::map<std::string, BinOp<int(int, int)>> calc;
calc["+"] = BinOp<int(int, int)>([](int x, int y){return x + y;});
calc["*"] = BinOp<int(int, int)>([](int x, int y){return x * y;});
calc["-"] = BinOp<int(int, int)>([](int x, int y){return x - y;});
calc["/"] = BinOp<int(int, int)>([](int x, int y){return x / y;});
calc["%"] = BinOp<int(int, int)>([](int x, int y){return x % y;});
for(const auto& e : calc)
std::cout << 10 << " " << e.first << " " << 12 <<
" = " << e.second(10, 12) << endl;
//BinOp<std::string(std::string, std::string)> bstr = [](string s1, string s2){return s1 + s2;}; // it doesn't work?
BinOp<std::string(std::string, std::string)> bstr;
bstr.fn = [](string s1, string s2){return s1 + s2;}; // works fine!
std::cout << bstr("Hello ", "Wold!") << std::endl;
std::cout << "\nDone!\n";
}
所以,尽管类bstr
具有可调用的构造函数,但为什么我无法从Lambda表达式初始化BinOp
?但是分配给bstr
就可以了:bstr = [](){}...
//有效!
任何提示或建议,批评家都表示赞赏。谢谢。
您可以在此处使用直接初始化来直接构建BinOp
:
BinOp<std::string(std::string, std::string)> bstr {[](string s1, string s2){return s1 + s2;}};
您的原始代码无法编译的原因很可能是因为您要求编译器执行两次转换,而它不会这样做。