ano*_*non 7 c++ macros pattern-matching
我喜欢Haskell风格的图案匹配.
我有我的C++代码如下:
ObjectPtr ptr;
if(ptr.isType<Foo>()) { // isType returns a bool
Ptr<Foo> p = ptr.convertAs<Foo>(); // convertAs returns a Ptr<Foo>
......
}
if(ptr.isType<Bar>()) {
Ptr<Bar> p = ptr.convertAs<Bar>();
......
}
Run Code Online (Sandbox Code Playgroud)
现在,有没有我可以定义的宏来简化这个?我一直在思考这个问题,但不能进一步简化它.
谢谢!
小智 7
dynamic_cast 似乎做你想做的事
struct A {
virtual ~A() {}
};
struct B : struct A { ... };
struct C : struct A { ... };
A * a = new C;
if ( C * c = dynamic_cast<C*>( a ) ) {
c->someCfunc();
}
else if ( B * b = dynamic_cast<B*>( a ) ) {
b->someBfunc();
}
else {
throw "Don't know that type";
}
Run Code Online (Sandbox Code Playgroud)
我喜欢Haskell风格的图案匹配.
然后在Haskell中编写程序.
你要做的是切换一种类型.如果他们想要避免虚函数,这是人们常做的事情.现在,后者是C++中OO的基石.如果你想避免它们,你为什么要用C++编程?
至于为什么这是不赞成的:想象一下,你有很多像这样的代码
if(ptr.isType<Foo>()) ...
if(ptr.isType<Bar>()) ...
Run Code Online (Sandbox Code Playgroud)
涂抹在你的代码上,然后有人来到并添加可能代表Baz的可能类型ptr.现在你正在寻找一个庞大的代码库,试图找到你切换类型的所有地方,并试图找出你需要添加Baz的地方.
并且,正如墨菲所说的那样,就在你完成的时候,它Foz也会被添加为一种类型.(或者,再想一想,如果墨菲有自己的方式,那么在你有机会完全添加之前它就会悄悄进入Baz.)
尝试使用RTTI在C++中模拟模式匹配样式是一个很好的想法,但它必然会有缺点,因为Haskell和Standard ML样式类型构造函数和C++子类之间存在一些显着差异.(注意:下面,我使用标准ML语法,因为我对它更熟悉.)
a::b::c::ds结合列表的前三个元件a,b和c,和该列表的其余部分ds).在C++中,您仍然需要在实际的嵌套结构中进行挖掘,除非您或其他人提出了比此处提出的更复杂的宏.datatype 'a option = NONE | SOME of 'a定义了一个新类型:'a option.构造函数NONE和SOME不类型,它们与类型的值'a option和'a -> 'a option分别.在C++中,当您定义子类Foo和Bar模拟类型构造函数时,您将获得新类型.SOME是第一类函数,它们构造它们所属的数据类型的值.例如,map SOME有类型'a list -> 'a option list.在C++中,使用子类来模拟类型构造函数,您无法获得此功能.最后,与以更典型的方式使用C++多态性相比,您是否从模拟模式匹配中获得了足够的好处?是否使用宏来使模拟模式匹配更加简洁(同时为其他读取代码的人进行模糊处理)值得?
我假设您的Ptr模板具有 NULL 指针的概念。
ObjectPtr ptr;
if(Ptr<Foo> p = ptr.convertAs<Foo>()) { // convertAs returns a NULL pointer if the conversion can't be done.
......
}
if(Ptr<Bar> p = ptr.convertAs<Bar>()) {
......
}
Run Code Online (Sandbox Code Playgroud)
不过,正如其他人所指出的,切换类型通常表明您在 C++ 中做错了什么。您应该考虑使用虚函数。