- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在D网站中,当您进入该网站时,前端会显示一个RPN计算器示例。由于 D 是我对强大的元编程(除了 Lisp)的引用,我想知道如何将一段代码从 C++ 转换为 D。代码段不需要相同,但应该相似。我放弃了使用宏:
部分D版本:
Array!int stack;
void binop(string op)()
{
stack[$ - 2] = mixin("stack[$ - 2] " ~
op ~ " stack[$ - 1]");
stack.removeBack();
writeln(stack[$ - 1]);
}
void process(in char[] token)
{
alias Ops = AliasSeq!("+", "-", "*", "/", "%");
Lswitch:
switch (token)
{
foreach (op; Ops)
{
case op:
binop!op();
break Lswitch;
}
case "=":
writeln(stack[$ - 1]);
stack.removeBack();
break;
default:
stack.insertBack(token.to!int);
break;
}
}
借助一些实用程序的部分 C++ 版本:
template <char Op>
void binop(std::vector<int> & s) {
//Returns std::minus<>, std::plus<>, etc.
using Op_t = opstr_to_func_object_t<Op>;
s[s.size() - 2] = Op_t{}(s[s.size() - 2], s[s.size() - 1]);
s.pop_back();
std::cout << s[s.size() - 1] << '\n';
}
template <char Op>
constexpr char op_name<Op> = std::integral_constant<char, Op>;
void process (std::string const & token, vector<int> & s) {
using namespace std;
constexpr auto ops = make_tuple(op_name<'+'>,
op_name<'-'>,
op_name<'*'>,
op_name<'/'>,
op_name<'%'>);
Lswitch:
switch (token[0]) {
//Cannot expand cases inline
// foreach([&](auto && elem) {
// constexpr auto op_str = decltype(elem)::value
//
// }, Ops{});
case "=":
std::cout << s[s.size() - 1] << '\n';
s.pop_back();
break;
default:
s.push_back(stoi(token));
}
}
我有一些问题:
有没有办法扩展内联代码并将其与环境混合,或者在不使用宏的情况下扩展像 D 中那样的优化开关?在 D 中有一个 foreach 可以扩展案例的代码内联。
有没有办法借助字符串的 constexpr 来模拟 switch?
我使用带有模板参数的外部函数,因为看起来lambdas 不能指定模板参数,所以我必须使用一个冗长的函数对象来捕获堆栈加上模板化的 operator()()。有没有办法解决这个问题并保持主要的功能过程和binop?
我认为 D 版本在元编程领域得分很高,但想知道如何在 C++ 中做到最好。
最佳答案
如果目标是干净的代码和/或尽可能多地使用语言功能,那么尝试将语言 1 的某些代码直接翻译成语言 2 很少是最佳解决方案。在忽略 D 实现的同时重写你的 RPN 计算器可能会更好......好吧,你的问题:
1)
Tldr:不直接。switch
的扩展 case 构造在它的原始语法中,没有宏,只是不存在。(像 eval
这样的东西并不存在,C++ 是一种“硬编译”语言,没有任何类型的解释器,程序中也没有嵌入式编译器。)
但是既然这里的一切都是基于仿函数/lambdas,为什么不制作一个映射(std::map
或其他任何东西)来将符号映射到函数,然后只调用符号的函数而不使用 切换
吗?
2)
是的,这是可能的。switch
单独只适用于整数,但正如你自己所说,一个 constexpr
函数接受一个字符串并返回一个 int,不同的字符串被映射到不同的 int(希望如此),可以使用。
这些案例看起来像
case myhashfunction("stringvalue"):
...
constexpr unsigned long myhashfunction(const char *) {...}
或者,使用用户定义的文字,例如。
case "stringvalue"_hash:
有人实际实现了 CRC32:https://stackoverflow.com/a/9842857/3134621
3)
Tldr:如果它应该在函数内部,则不。
虽然 lambda 中的 auto
关键字具有一些类似模板的功能,但它不如全功能模板强大(例如,没有文字,不强制多个参数使用相同的类型 等.).
在没有 lambda 语法快捷方式的情况下,在函数中创建仿函数类也是不可能的:函数中的类定义不能使用模板。
因此,您需要在将使用 lambda/仿函数的函数之外添加一些东西。
关于C++ 与 D 的示例。前端程序RPN计算器来自D主页对比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33229762/
我尝试将中缀表示法表达式转换为后缀表示法 (RPN)。这是函数: String createRPN(String infix) { Stack *stack = node_alloc(1);
目前,我正在制作一个计算器,输入数学表达式并使用RPn进行计算。因此,我使用中缀到后缀转换器函数来转换它。计算器的工作原理是将数字插入堆栈并检测运算符。但我的计算器有一个缺陷,它无法处理负数除法,例如
我有一个程序应该将表达式转换为反向波兰表示法,然后在执行计算后显示答案。现在它不能正确执行计算。例如,如果我输入 5+2+5,它出于某种原因只注册了 5+2。谁能告诉我我做错了什么? #include
环境安装: pycuda安装: 开源项目信息 fasterRCNN的训练 faster rcnn onnx实践 第3步测试结果: 第4步测试结果: 单张图片测试代码: 多张图片预测代码: 第5步做了修
我的代码遇到问题。它似乎只适用于单位数字 int。我不知道如何创建一个适用于大于 9 的 int 的函数。此外,我不知道如果字符串为空,如何结束程序。 这是我的代码: #include #inclu
我试图解决的一本 C 编程书中的问题是这个,我很难理解,尤其是 pop() 函数在这种情况下是如何工作的: For example, 1 + 2 would be written 1 2 + in R
我正在尝试创建一个简单的 RPN 解析器,它只接受单位数字值和 +-*/运算符。我使用堆栈来存储原始输入,但在打印输出时遇到问题。 当我运行调试时,它给出错误消息“程序收到信号 SIGSEGV,段错误
我正在尝试将数学表达式转换为 RPN,然后对它们执行符号微分,但是我遇到了一些函数,例如 sin() cos() tan()... ln() sqrt() 等。我的表达式解析器仅适用于更简单的情况,例
我正在设计一个程序来对流式数据执行某些操作。操作由运行时提供的 RPN(逆向抛光表示法)表达式定义。数据从文件源流式传输,一次一个固定大小的部分。操作引用一些当前输入的数据部分,例如 data[1]。
我目前正在为一个必须通过一堆整数和各种函数运行的类构建 RPN 计算器。它还必须通过 cin 语句获取输入,然后将其分类为整数或操作数,然后将其压入堆栈或从类中启动适当的函数进行计算。 其中大部分我已
你好)这是我将中缀表达式转换为后缀表达式的代码,但是我只是不明白如何评估我得到的后缀表达式,我将非常感谢任何提示。我不是要代码,尽管这会有所帮助。 #include #include #inclu
我不明白该怎么做?有人可以解释一下如何将 ac+ ac+* 转换为二叉树形式吗?我需要将此表达式转换为该树的完整括号字符串表示形式。 最佳答案 您需要按照处理后缀输入的方式构建树。但是,当您遇到操作时
我已经实现了以下“tree sizer”,但在某些情况下它会失败,下面的示例在应该返回大小 4 时返回大小 2,任何人都可以帮助我。我已经写了好几次了,没有用,一直失败。 def getRPNdept
我所说的使用是指它在许多计算器中的使用,例如 HP35- 我的猜测(和困惑)是 - postfix 实际上更有效地存储内存 -(所以发表评论 here)。 (混淆 - 两者的评估算法与堆栈相似) 当时
我遇到了一个任务,它让你检查作为参数传递给你的方法/函数的字符串是否是反向波兰表示法意义上的正确语句。它可以包含小写字母、运算符号和整数。有没有比分别读取每个字符并实际尝试计算整个表达式更快的方法来检
有什么方法可以将“正常”数学符号解释为逆波兰符号 (RPN)..? 例如1) 2 + 3*4 - 1 = 234*+1-2) 5 (4-8) = 548- 你可以假设遵循 BODMAS 规则并且必须首
给出了原始配方here (您也可以尝试您的程序的正确性)。 附加规则: 1.程序应该从标准输入读取并写入标准输出。 2. 程序应该向调用系统/程序返回零。 3. 程序应使用 gcc -O2 -lm -
我正在尝试使用 foldr 编写一个反向波兰符号评估器,这是我目前所拥有的: step :: [Int] -> String -> [Int] step (x * y):ys "*" = (x:y:y
数学表达式通常用中缀符号表示。出于评估目的,我们可以将其更改为后缀(反向抛光)表示法(使用像 Shunting-Yard 这样的算法),然后使用堆栈评估后缀表示法。 我发现计算器使用这种技术,但是今天
有人可以解释一下为什么我在 myString 上使用 strok() 后总是出现乱码吗?我的输出图片位于底部。我尝试将 myString 中的每个元素初始化为 NULL 字符,但我的代码仍然不起作用:
我是一名优秀的程序员,十分优秀!