如何为每个宏参数声明类型

How to declare type for each macro argument?

本文关键字:参数 声明 类型      更新时间:2023-10-16

例如

 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__ )

您提供的上下文太少,无法在最后一个参数之后决定处理逗号(或缺少逗号(的正确策略。

但我认为这应该足以让你走上正确的(或工作(轨道。

最后的想法是,听起来好像使用可变参数模板而不是宏可以更好地解决您的问题。宏适用于无法以其他方式处理的情况,如上面显示的字符串文本示例。但同样,你提供的上下文太少了。