我刚刚发现,在将参数传递给宏时,不能总是使用大括号初始化。当ASSERT()宏编译失败时,我发现了这一点。然而,下面的示例说明了这个问题:
#include <iostream>
#include <string>
using namespace std;
#define PRINT_SIZE( f ) cout << "Size=" << (f).size() << endl;
int main()
{
PRINT_SIZE( string("ABC") ); // OK, prints: "Size=3"
PRINT_SIZE( string{"ABC"} ); // OK, prints: "Size=3"
PRINT_SIZE( string("ABCDEF",3) ); // OK, prints: "Size=3"
PRINT_SIZE( string{"ABCDEF",3} ); // Error: macro 'PRINT_SIZE' passed 2 arguments, but takes just 1
return 0;
}宏不能用于大括号初始化的原因吗?
编辑:
此后,我发现您也可以使用各种宏,这很好地解决了这个问题:
#include <iostream>
#include <string>
using namespace std;
#define PRINT_SIZE( ... ) cout << "Size=" << (__VA_ARGS__).size() << endl;
int main()
{
PRINT_SIZE( string("ABC") ); // OK, prints: "Size=3"
PRINT_SIZE( string{"ABC"} ); // OK, prints: "Size=3"
PRINT_SIZE( string("ABCDEF",3) ); // OK, prints: "Size=3"
PRINT_SIZE( string{"ABCDEF",3} ); // OK, prints: "Size=3"
return 0;
}发布于 2015-04-11 14:21:31
列表被分成几个宏参数。当你写
PRINT_SIZE( string{"ABCDEF",3} );这会尝试用两个参数展开宏PRINT_SIZE,一个是string{"ABCDEF",另一个是3},这两个参数都失败了。在许多情况下(包括您的情况),可以通过添加另一对括号来解决这一问题:
PRINT_SIZE( (string{"ABCDEF",3}) );这些括号阻止了参数的分裂,从而使PRINT_SIZE用单个参数(string{"ABCDEF",3})展开(注意括号是参数的一部分)。
发布于 2015-04-11 14:22:21
是的,这是有原因的:预处理器不知道大括号。它只尊重字符串文字和括号,对其他C/C++语言结构则一无所知。因此,呼叫
PRINT_SIZE( string{"ABCDEF",3} );被解析为具有两个参数string{"ABCDEF"和3}的宏调用。由于宏PRINT_SIZE()只需要一个参数,所以预处理器就会退出。请注意,C++编译器此时甚至还没有被调用!
发布于 2021-05-29 15:26:59
这个怎么样?
#define SOME_BRACE \
{ \
6, 8, 1, 3, 7, \
1, 4, 2, 0, 9 \
}
#define BRACE_SIZE(brace) (sizeof((int[]) SOME_BRACE) / sizeof(int))
int main(int argc, char *argv[])
{
int array[BRACE_SIZE(SOME_BRACE)] = SOME_BRACE, i, s;
for (i = 0, s = 0; i < BRACE_SIZE(SOME_BRACE); i++) {
s = s + array[i];
}
/* 41 is expected */
return s;
}https://stackoverflow.com/questions/29578902
复制相似问题