标签: variadic-macros

向variadic宏添加默认参数

是否有可能在可变参数宏中的变量参数之前添加默认参数?例如,我有像宏的版本

#define MACRO(arg1, ...) func(arg1, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

我想在变量参数之前在宏中添加另外2个默认参数,这样它就不会影响以前的版本.喜欢:

#define MACRO(arg1, arg2 = "", arg3 = "", ...) func(arg1, arg2, arg3, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激.

c++ variadic-functions c-preprocessor variadic-macros

5
推荐指数
2
解决办法
6552
查看次数

如何单独输出发送到仅采用可变参数的宏的第一个参数

我尝试获取发送到可变参数宏的第一个实际参数.这是我试过的,哪些在VS2010中不起作用:

#define FIRST_ARG(N, ...) N
#define MY_MACRO(...) decltype(FIRST_ARG(__VA_ARGS__))
Run Code Online (Sandbox Code Playgroud)

当我查看预处理器输出时,我看到FIRST_ARG返回发送给MY_MACRO... 的整个参数列表

另一方面,当我尝试:

FIRST_ARG(1,2,3)
Run Code Online (Sandbox Code Playgroud)

它按预期扩展到1.

这似乎是臭名昭着的两级concat宏解决问题的逆转.我知道"宏参数在插入宏体之前已完全展开"但这似乎对我没有帮助,因为我不明白这意味着什么......和__VA_ARGS__

显然是__VA_ARGS__绑定,N只是稍后评估.我尝试了几种额外的宏观方法,但没有用.

c++ macros c-preprocessor variadic-macros c++11

5
推荐指数
1
解决办法
4053
查看次数

使用可变参数宏或模板来实现一组函数

我有一组用于实例化和初始化一组对象的方法.它们看起来几乎相同,除了传递给Init函数的参数数量:

ObjectType* CreateObjectType(Arg1 a1, Arg2 arg2, ... ArgN aN)
{
    ObjectType* object = new ObjectType();
    [...]
    object->Init(this, a1, a2, ..., aN);
    [...]
    return object;
}
Run Code Online (Sandbox Code Playgroud)

请注意,除了要传递给Init函数之外,不能在任何地方使用参数.

我想找到一种方法来实现所有这些,而无需为每个对象类型复制代码.


我尝试使用可变参数宏,结果如下(无效):

#define CREATE_OBJECT_IMPL(ObjectType, ...)    \
ObjectType* Create##ObjectType##(__VA_ARGS__)  \
{                                              \
    ObjectType* object = new ObjectType();     \
    [...]
    object->Init(this, ##__VA_ARGS__);         \
    [...]
    return object;                             \
}

// This is the result I am trying to achieve :
CREATE_OBJECT_IMPL(MyFirstObject, bool, float)
CREATE_OBJECT_IMPL(MySecondObject, int)
CREATE_OBJECT_IMPL(MyThirdObject)
Run Code Online (Sandbox Code Playgroud)

现在,在这个实现中,我使用VA_ARGS两次,两次都不正确:

  • 在第一种情况下,我想要一个包含我指定类型的参数列表(Arg1 a1,Arg2 a2 ......)

  • 在第二种情况下,我想通过它们的名称(Init(a1,a2 ...))来调用这些参数. …

c++ variadic-templates variadic-macros

5
推荐指数
1
解决办法
3018
查看次数

检测C宏中是否存在参数

如何定义一个C宏IFARGS(YES, NO, ...),以便IFARGS在没有其他参数的情况下进行NO调用,并IFARGS使用一个或多个参数进行调用YES

我有一个使用GCC的答案(见下文),但如果可能的话,我更喜欢C99(或其不可能的证明).

c c-preprocessor variadic-macros

5
推荐指数
2
解决办法
1333
查看次数

什么是#__VA_ARGS__应该在没有传递参数时生成?

示例代码:

#define FOO(...) You passed: #__VA_ARGS__
FOO(1,2,3)
FOO()
Run Code Online (Sandbox Code Playgroud)

使用Visual C++(版本14 CTP)进行预处理,得到:

You passed: "1,2,3"
You passed:
Run Code Online (Sandbox Code Playgroud)

在最后一行,#__VA_ARGS__变成了虚无.我希望它变成"".

对于应该发生的事情,是否有明确的参考?我用Google搜索了很多但却找不到它.

任何建议的解决方案也很有用.

c++ c-preprocessor variadic-macros

5
推荐指数
1
解决办法
2117
查看次数

使用宏迭代生成函数声明

我正在尝试使用宏生成函数声明

/* goal: generate int f(int a, float b) */
template<typename P>
struct ptype;

template<typename P>
struct ptype<void(P)> { typedef P type; };

#define NAMEe
#define COMMAe
#define COMMA ,

#define NAME(N) N PARAMS
#define PARAMS(P, ...) COMMA ## __VA_ARGS__ P NAME ## __VA_ARGS__
#define PARAM_ITER(P) P NAME

#define PROTO(R, N, P)  \
  ptype<void R>::type N (PARAM_ITER P (,e))

PROTO((int), f, (int)(a)(float)(b));
Run Code Online (Sandbox Code Playgroud)

它将使用具有空的宏参数来迭代地处理下一个(name)(type)NAMEPARAMS分别...。但海湾合作委员会抱怨

prototype.hpp:20:35: warning: ISO C99 requires rest arguments …
Run Code Online (Sandbox Code Playgroud)

c++ c99 c-preprocessor variadic-macros c++11

4
推荐指数
1
解决办法
5212
查看次数

编写一个使用传递的参数名称的可变参数宏

我想写一个变量宏,它以某种方式知道传递的参数的名称.例如:

代码:

int x = 2;
float f = 4.6;
char c = 'A';
char* str = "Bla bla";
PRINT("%d  %f %c  %s", x, f, c, str);     // calling the macro
Run Code Online (Sandbox Code Playgroud)

应产生输出

x=2 f=4.6 c=A str=Bla bla.
Run Code Online (Sandbox Code Playgroud)

希望有人知道答案.

c macros variadic-functions variadic-macros

4
推荐指数
1
解决办法
301
查看次数

变体宏:粘贴标记的扩展

我想知道是否有可能"嵌套"可变宏调用.我只关心GCC和Clang.我的宏定义如下:

/**
 * @brief Invoke an instance method.
 */
#define $(obj, method, ...) \
    ({ \
        typeof(obj) _obj = obj; \
        _obj->interface->method(_obj, ## __VA_ARGS__); \
    })
Run Code Online (Sandbox Code Playgroud)

我使用它在我的OO框架中方便地调用"实例方法"(https://github.com/jdolan/objectively):

$(array, addObject, obj);
Run Code Online (Sandbox Code Playgroud)

工作老板.不幸的是,我还没有找到一种允许嵌套这些调用的方法,这在某些情况下非常有用; 例如:

/**
 * @see MutableSetInterface::addObjectsFromArray(MutableSet *, const Array *)
 */
static void addObjectsFromArray(MutableSet *self, const Array *array) {

    if (array) {
        for (size_t i = 0; i < array->count; i++) {
            $(self, addObject, $(array, objectAtIndex, i));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的嵌套可变参数宏调用无法编译,因为内部调用永远不会扩展.是否有可能解决这个问题,或者我已经将预处理器滥用到了极限?:)

c macros gcc clang variadic-macros

4
推荐指数
1
解决办法
365
查看次数

在## 运算符存在的情况下,可变参数 GNU C 预处理器宏的惊人扩展

如果我们定义一个宏

#define M(x, ...) { x, __VA_ARGS__ }
Run Code Online (Sandbox Code Playgroud)

然后使用它传递自身作为参数

M(M(1, 2), M(3, 4), M(5, 6))
Run Code Online (Sandbox Code Playgroud)

然后它扩展到预期的形式:

{ { 1, 2 }, { 3, 4 }, { 5, 6 } }
Run Code Online (Sandbox Code Playgroud)

但是,当我们使用##运算符时(为了防止在单参数调用的情况下在输出中出现悬空逗号,如GCC 手册中所述),即

#define M0(x, ...) { x, ## __VA_ARGS__ }
Run Code Online (Sandbox Code Playgroud)

那么在参数的扩展

M0(M0(1,2), M0(3,4), M0(5,6))
Run Code Online (Sandbox Code Playgroud)

似乎在第一个参数后停止,即我们得到:

{ { 1,2 }, M0(3,4), M0(5,6) }
Run Code Online (Sandbox Code Playgroud)

这种行为是一个错误,还是源于某些原则?

(我也用clang检查过它,它的行为方式与GCC相同)

c gcc c-preprocessor variadic-macros

4
推荐指数
1
解决办法
135
查看次数

可变参数宏无法编译

我有 2 个可变宏,其中一个可以正常编译,另一个则不能:

    #define ASSERT(x, ...)           assert_log(x, __FILE__, __LINE__, __VA_ARGS__)
    #define TRACE (x, ...)           trace(x, __FILE__, __LINE__, __VA_ARGS__)
...

libs/defs.h:16:71: error: __VA_ARGS__ can only appear in the expansion of a C99 variadic macro [-Werror]
   16 |         #define TRACE (x, ...)           trace(x, __FILE__, __LINE__, __VA_ARGS__)
      |                                                                       ^
Run Code Online (Sandbox Code Playgroud)

他们宣布的签名:

void assert_log(int, const char*, int, const char* , ...);
void trace(int, const char*, int, const char* , ...);
Run Code Online (Sandbox Code Playgroud)

编译标志:

CFLAGS= \
    -Wextra \
    -Werror \
    -Wall \
    -Wfloat-equal \
    -Wundef \
    -Wshadow \ …
Run Code Online (Sandbox Code Playgroud)

c preprocessor variadic-macros

4
推荐指数
1
解决办法
50
查看次数