Мне нужен макрос, который будет вызывать функции с различным числом аргументов, или макрос, который будет генерировать действительный список аргументов из его (повторяющихся) параметров.
Я согласен с явным предоставлением информации о числеаргументов к макросу, но я не могу понять, как создать список аргументов для функции - я всегда натыкаюсь на макросы, возвращающие выражения, а не на дерево токенов.
Я создал следующую площадкупример :
macro_rules! call (
($f: expr, $($params:tt)*) => {
$f(make_params!($($params:tt)*))
};
);
macro_rules! make_params {
() => {};
(I $($params: tt)*) => {
1, make_params!($($params:tt)*)
};
}
fn foo(a: i32, b: i32, c: i32) {
println!("foo: {} {} {}", a, b, c);
}
fn bar(a: i32, b: i32) {
println!("bar: {} {}", a, b);
}
fn main() {
call!(foo, I I I);
call!(bar, I I);
}
Компилятор жалуется на следующее:
error: macro expansion ignores token `,` and any following
--> src/main.rs:10:10
|
10 | 1, make_params!($($params:tt)*)
| ^
|
note: caused by the macro expansion here; the usage of `make_params!` is likely invalid in expression context
--> src/main.rs:3:12
|
3 | $f(make_params!($($params:tt)*))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
Как можно трактовать возврат make_params!
как поток токенов (или такой), а невыражение?
Мой реальный пример использования немного сложнее, чем этот игрушечный пример.Мои функции имеют несколько типов параметров, которые создаются по-разному.В моем случае простое создание макросов call1
, call2!
, ... не кажется хорошим решением, так как мне понадобятся call_IIOOI
, call_IIIO
и т. Д.