我有一个宏,它创建一个结构和一堆支持函数和特征实现.这个问题的有趣之处在于:
macro_rules! make_struct {
($name: ident) => {
struct $name;
}
}
Run Code Online (Sandbox Code Playgroud)
这可以按照您的期望工作:
make_struct!(MyStruct);
Run Code Online (Sandbox Code Playgroud)
如果我想制作参数化类型,我运气不好:
make_struct!(AnotherStruct<T: SomeTrait>);
test.rs:8:27: 8:28 error: no rules expected the token `<`
test.rs:8 make_struct!(AnotherStruct<T: SomeTrait>);
Run Code Online (Sandbox Code Playgroud)
结构的名称是一个ident所以我不能只在宏args中更改它(例如to ty):
test.rs:3:16: 3:21 error: expected ident, found `MyStruct`
test.rs:3 struct $name;
Run Code Online (Sandbox Code Playgroud)
那么如何编写这个宏来处理这两个呢?或者我需要分开吗?在后一种情况下,宏看起来像什么?
我正在使用纠结的条件网重构一个3000 + -line类,并切换到一组工作类.以前,构造函数的一部分将通过以下代码选择要使用的"类型"事物:
enum Type { FOO, BAR, BAZ };
Type choices[] = { FOO, FOO, BAR, BAZ }; // weighted towards FOO
m_type = choices[rand()%4];
[...later...]
void Run() {
switch (m_type) {
case FOO: do_foo(); break;
case BAR: do_bar(); break;
case BAZ: do_baz(); break;
}
}
Run Code Online (Sandbox Code Playgroud)
重构后我有单独的TypeFoo,TypeBar与TypeBaz类,每个人都有自己Run()的方法来做好自己的工作.可悲的是,它的类选择代码很复杂.我不知道有什么办法可以保留一个可能的类列表来构建,所以我有这个:
Type *m_type;
switch (mrand()%4) {
case 0: case 1: m_type = new TypeFoo(); break;
case 1: m_type = new TypeBar(); break;
case 2: m_type …Run Code Online (Sandbox Code Playgroud) 我想安排一些事情,对于一个类Foo,这是有效的:
Foo *f = new Foo()
Run Code Online (Sandbox Code Playgroud)
但这不是(最好是编译时错误):
Foo f;
Run Code Online (Sandbox Code Playgroud)
可以这样做吗?
具体原因是Foo实际上是一个跟踪类,可以使另一个堆分配的对象出现在脚本环境中.Foo的内部保持从脚本引用到C++对象的映射.跟踪对象将使用如下:
Thing *t = new Thing();
(new FooThing(t))->PushToScriptStack();
Run Code Online (Sandbox Code Playgroud)
如果跟踪对象在堆栈上,则指针在范围结束时变为无效,并且我在跟踪数据中留下了悬空指针.
我所有这些都运作良好,我只是想寻求一些额外的保护.