如何为每个宏参数声明类型
How to declare type for each macro argument?
例如
DECL_TYPE(a) becomes decltype(a)
DECL_TYPE(a, b) becomes decltype(a), decltype(b)
DECL_TYPE(a, b, c) becomes decltype(a), decltype(b), decltype(c)
如何定义宏DECL_TYPE
?
好吧,让我们从计算参数数量的基本问题开始。
它可以是这样的:
纳格斯·#pragma once
// Copyright (c) 2013 Alf P. Steinbach.
//
// The MM_NARGS macro evaluates to the number of arguments that have been
// passed to it.
//
// Based on original code by Laurent Deniau,
// "__VA_NARG__," 17 January 2006, <comp.std.c> (29 November 2007).
// https://groups.google.com/forum/?fromgroups=#!topic/comp.std.c/d-6Mj5Lko_s
#include <rfc/macro_magic/invoke.h> // MM_INVOKE
#include <rfc/macro_magic/concat.h> // MM_CONCAT
#define MM_ARG_N(
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10,
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,
_61,_62,_63,N,...) N
#define MM_RSEQ_N()
63,62,61,60,
59,58,57,56,55,54,53,52,51,50,
49,48,47,46,45,44,43,42,41,40,
39,38,37,36,35,34,33,32,31,30,
29,28,27,26,25,24,23,22,21,20,
19,18,17,16,15,14,13,12,11,10,
9,8,7,6,5,4,3,2,1,0
#ifdef MM_USE_ORIGINAL_DEFINITION
#define MM_NARGS_(...) MM_ARG_N( __VA_ARGS__ )
#define MM_NARGS( ...) MM_NARGS_( __VA_ARGS__, MM_RSEQ_N() )
#else
#define MM_NARGS_AUX( ... ) MM_INVOKE( MM_ARG_N, ( __VA_ARGS__ ) )
#define MM_NARGS( ... ) MM_NARGS_AUX( __VA_ARGS__, MM_RSEQ_N() )
#endif
使用这两个帮助程序文件:
invoke.h#pragma once
// Copyright (c) 2013 Alf P. Steinbach.
#define MM_INVOKE( macro, args ) macro args
#define MM_INVOKE_B( macro, args ) macro args // For nested invocation with g++.
康卡特·#pragma once
// Copyright (c) 2013 Alf P. Steinbach.
#define MM_CONCAT__( a, b ) a ## b
#define MM_CONCAT_( a, b ) MM_CONCAT__( a, b )
#define MM_CONCAT( a, b ) MM_CONCAT_( a, b )
自从我摆弄这段代码以来已经有一段时间了,我似乎想起了连接的一些问题。但至少存在上述代码起作用的上下文。它通常可能有效。
将给定宏应用于参数序列的宏:
应用.h#pragma once
// Copyright (c) 2013 Alf P. Steinbach.
#include <rfc/macro_magic/nargs.h> // MM_INVOKE, MM_INVOKE_B, MM_CONCAT, MM_NARGS
#define MM_APPLY_1( macroname, a1 )
MM_INVOKE_B( macroname, (a1) )
#define MM_APPLY_2( macroname, a1, a2 )
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_1( macroname, a2 )
#define MM_APPLY_3( macroname, a1, a2, a3 )
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_2( macroname, a2, a3 )
#define MM_APPLY_4( macroname, a1, a2, a3, a4 )
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_3( macroname, a2, a3, a4 )
#define MM_APPLY_5( macroname, a1, a2, a3, a4, a5 )
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_4( macroname, a2, a3, a4, a5 )
#define MM_APPLY_6( macroname, a1, a2, a3, a4, a5, a6 )
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_5( macroname, a2, a3, a4, a5, a6 )
#define MM_APPLY_7( macroname, a1, a2, a3, a4, a5, a6, a7 )
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_6( macroname, a2, a3, a4, a5, a6, a7 )
#define MM_APPLY_8( macroname, a1, a2, a3, a4, a5, a6, a7, a8 )
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_7( macroname, a2, a3, a4, a5, a6, a7, a8 )
#define MM_APPLY_9( macroname, a1, a2, a3, a4, a5, a6, a7, a8, a9 )
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_8( macroname, a2, a3, a4, a5, a6, a7, a8, a9 )
#define MM_APPLY_10( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_9( macroname, a2, a3, a4, a5, a6, a7, a8, a9, a10 )
#define MM_APPLY_11( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_10( macroname, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 )
#define MM_APPLY_12( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_11( macroname, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 )
#define MM_APPLY_13( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_12( macroname,
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13
)
#define MM_APPLY_14( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_13( macroname,
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14
)
#define MM_APPLY_15( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_14( macroname,
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15
)
#define MM_APPLY_16( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_15( macroname,
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15, a16
)
#define MM_APPLY_17( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_16( macroname,
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15, a16, a17
)
#define MM_APPLY_18( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_17( macroname,
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15, a16, a17, a18
)
#define MM_APPLY_19( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_18( macroname,
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15, a16, a17, a18, a19
)
#define MM_APPLY_20( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_19( macroname,
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15, a16, a17, a18, a19, a20
)
#define MM_APPLY_21( macroname,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20,
a21
)
MM_INVOKE_B( macroname, (a1) )
MM_APPLY_20( macroname,
a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15, a16, a17, a18, a19, a20, a21
)
#define MM_APPLY( macroname, ... )
MM_INVOKE(
MM_CONCAT( MM_APPLY_, MM_NARGS( __VA_ARGS__ ) ),
( macroname, __VA_ARGS__ )
)
现在不是很好吗。
所以很少重复。
一个示例用例:
#ifdef _WIN32
namespace cppx{ typedef wchar_t Raw_syschar; } // Implies UTF-16 encoding.
# define CPPX_SYSCHAR_IS_WIDE 1
# define CPPX_WITH_SYSCHAR_PREFIX_( lit ) L##lit
#else
namespace cppx{ typedef char Raw_syschar; } // Implies UTF-8 encoding.
# define CPPX_SYSCHAR_IS_WIDE 0
# define CPPX_WITH_SYSCHAR_PREFIX_( lit ) lit
#endif
#define CPPX_WITH_SYSCHAR_PREFIX( ... )
MM_APPLY( CPPX_WITH_SYSCHAR_PREFIX_, __VA_ARGS__ )
#define CPPX_AS_SYSCHAR( ... )
::cppx::typed( CPPX_WITH_SYSCHAR_PREFIX( __VA_ARGS__ ) )
#define CPPX_U CPPX_AS_SYSCHAR
#define CPPX_RAW_U CPPX_WITH_SYSCHAR_PREFIX
它允许一个人写例如
auto const x = CPPX_U
(
"First linen",
"Second line"
);
并将其翻译成
auto const x = cppx::typed( L"First linen" L"Second line" );
在您的特定示例案例中,您将定义如下代码
#define APPLY_DECL_TYPE( x ) decltype( x ),
#define DECL_TYPE( ... ) MM_APPLY( APPLY_DECL_TYPE, __VA_ARGS__ )
您提供的上下文太少,无法在最后一个参数之后决定处理逗号(或缺少逗号(的正确策略。
但我认为这应该足以让你走上正确的(或工作(轨道。
最后的想法是,听起来好像使用可变参数模板而不是宏可以更好地解决您的问题。宏适用于无法以其他方式处理的情况,如上面显示的字符串文本示例。但同样,你提供的上下文太少了。
相关文章:
- Arduino C++在构造函数中用参数声明对象数组
- 如何使用参数声明实例?
- 从非类型模板参数声明 constexpr 数组的可移植方法
- 用相同的参数声明两个构造函数的最偶像化的方法是什么?
- 在实现文件中使用模板参数声明方法
- 使用 std::move 将参数传递给函数,如果该参数声明为按值传递或使用移动操作数 &&,是否有区别?
- 如果我提前将参数声明为变量而不是将它们内联写入函数调用,那有什么区别(在内存方面)?
- 为什么重载运算符>在参数声明 const 时不起作用?
- 字符串无法启动参数声明
- 视觉C++:即使使用关键字,参数声明也会隐藏类成员"this"
- C 迭代器从Typedef std :: Map作为模板参数声明
- 参数声明中的"const T const"
- 如何处理"警告:在参数声明中使用'auto'仅适用于 -fconcepts"
- 将容器作为模板参数声明过滤
- 同时使用模板和参数声明对象
- 从variadic模板参数声明成员变量
- 在 C++ 中,为什么我们在重载函数中将引用参数声明为 const
- 在C++中,是否可以使用定义中未使用的模板参数声明模板结构?
- C++ "无法将参数声明为抽象类型
- 默认参数声明:为什么默认字符串参数必须是 const