我想构造一个宏,它接受可变数量的参数,并以类似于下面示例的格式将第一个参数分配给每个后续参数:
Call: MACRO(F,A)
Result: F:A
Call: MACRO(F,A,B,C)
Result: F:A F:B F:C
我已经看到https://github.com/swansontec/map-macro和递归的一般概念解决方法:
#define EVAL0(...) __VA_ARGS__
#define EVAL1(...) EVAL0 (EVAL0 (EVAL0 (__VA_ARGS__)))
#define EVAL2(...) EVAL1 (EVAL1 (EVAL1 (__VA_ARGS__)))
#define EVAL3(...) EVAL2 (EVAL2 (EVAL2 (__VA_ARGS__)))
#define EVAL4(...) EVAL3 (EVAL3 (EVAL3 (__VA_ARGS__)))
#define EVAL(...) EVAL4 (EVAL4 (EVAL4 (__VA_ARGS__)))
但我无法理解如何将此问题应用于我的问题。任何人都可以提供一个例子来实现上面显示的结果吗?谢谢!
答案 0 :(得分:6)
使用Boost.PP:
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#define TRANSFORM(r, data, elem) data:elem
#define MACRO(F, ...) \
BOOST_PP_SEQ_FOR_EACH(TRANSFORM, F, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
Demo。这将(AFAIR)最多可以处理255个参数。
答案 1 :(得分:4)
您可以使用NARGS
宏来计算可变参数宏的参数,以创建递归宏,为您的所有aguments应用前缀:
#define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1, 0)
#define NARGS_(_5, _4, _3, _2, _1, N, ...) N
#define CONC(A, B) CONC_(A, B)
#define CONC_(A, B) A##B
#define PREFIX_0(P, E) E
#define PREFIX_1(P, E) P:E
#define PREFIX_2(P, E, ...) P:E PREFIX_1(P, __VA_ARGS__)
#define PREFIX_3(P, E, ...) P:E PREFIX_2(P, __VA_ARGS__)
#define PREFIX_4(P, E, ...) P:E PREFIX_3(P, __VA_ARGS__)
#define PREFIX_5(P, E, ...) P:E PREFIX_4(P, __VA_ARGS__)
#define PREFIX(P, ...) CONC(PREFIX_, NARGS(__VA_ARGS__)) (P, __VA_ARGS__)
PREFIX(F, A)
PREFIX(F, A, B, C, D)
为简洁起见,参数总数限制为5,但您可以通过以明显的方式扩展NARGS
和NARGS_
以及撰写更多PREFIX_X
来扩展此解决方案宏。
答案 2 :(得分:0)
您可以将自己的宏传递给MAP宏:
示例强>
#include<iostream>
struct F {
static void A() { std::cout << "A\n"; }
static void B() { std::cout << "B\n"; }
static void C() { std::cout << "C\n"; }
};
int main()
{
#define CALL_MEMBER(Member) F::Member();
#define CALL_STRUCTURE(Structure) Structure::CALL_MEMBER
#define MACRO(Structure, ...) MAP(CALL_STRUCTURE(Structure), __VA_ARGS__)
MACRO(F, A)
MACRO(F, A, B, C)
}
来自https://github.com/swansontec/map-macro
的MAP宏/*
* Copyright (C) 2012 William Swanson
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or
* their institutions shall not be used in advertising or otherwise to
* promote the sale, use or other dealings in this Software without
* prior written authorization from the authors.
*/
#ifndef MAP_H_INCLUDED
#define MAP_H_INCLUDED
#define EVAL0(...) __VA_ARGS__
#define EVAL1(...) EVAL0 (EVAL0 (EVAL0 (__VA_ARGS__)))
#define EVAL2(...) EVAL1 (EVAL1 (EVAL1 (__VA_ARGS__)))
#define EVAL3(...) EVAL2 (EVAL2 (EVAL2 (__VA_ARGS__)))
#define EVAL4(...) EVAL3 (EVAL3 (EVAL3 (__VA_ARGS__)))
#define EVAL(...) EVAL4 (EVAL4 (EVAL4 (__VA_ARGS__)))
#define MAP_END(...)
#define MAP_OUT
#define MAP_GET_END() 0, MAP_END
#define MAP_NEXT0(test, next, ...) next MAP_OUT
#define MAP_NEXT1(test, next) MAP_NEXT0 (test, next, 0)
#define MAP_NEXT(test, next) MAP_NEXT1 (MAP_GET_END test, next)
#define MAP0(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP1) (f, peek, __VA_ARGS__)
#define MAP1(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP0) (f, peek, __VA_ARGS__)
#define MAP(f, ...) EVAL (MAP1 (f, __VA_ARGS__, (), 0))
#endif