我在C ++和任何编译器中编写编译器,它需要极大量的模式匹配和动态强制转换。在Rust,Haskell和OCaml等语言中,我可以轻松地破坏类型,例如:
match node {
Binary{ left, right, operator } => { .. }
_ => { .. }
}
在C ++中,我能做的最好的是:
if (auto bin = dynamic_cast<Binary*>(node)) { ... }
else if (...) { ... }
如果你在场景中引入智能指针,那么这是非常有限和丑陋的。例如,如果我需要匹配两件事:
bool matched = false;
if (auto m1 = dynamic_cast<Foo*>(a)) {
if (auto m2 = dynamic_cast<Bar*>(b)) {
matched = true;
}
}
if (!matched) {
// This is because C++ does not allow you to declare two variables inside the condition...
}
我知道Mach7库但是老实说看起来很糟糕,因为你需要为你的结构编写元数据(同时我也注意到它有很多错误和限制)。
有没有办法让这些比赛更具可读性?
答案 0 :(得分:1)
以下似乎是避免两次匹配的双重方式 - 并且可以很容易地推广:
template <class T1,class T2> struct castPairstruct : public std::pair<T1,T2> {
operator bool() {return first && second;}
castPairstruct<T1,T2>(T1 a,T2 b):std::pair<T1,T2>(a,b) {;}
};
template <class T1,class T2> castPairstruct<T1,T2> castPair(T1 a,T2 b){
return castPairstruct<T1,T2>(a,b);
}
if (auto j=castPair(dynamic_cast<Foo*>(a),dynamic_cast<Bar*>(b)) {