我刚刚发现,在将参数传递给宏时,不能总是使用大括号初始化.当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;
}
Run Code Online (Sandbox Code Playgroud)
有没有理由不能使大括号初始化使用宏?
编辑:
我后来发现你也可以使用一个可变参数宏,这完全解决了这个问题:
#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;
}
Run Code Online (Sandbox Code Playgroud)
Win*_*ute 14
该列表分为几个宏参数.当你写作
PRINT_SIZE( string{"ABCDEF",3} );
Run Code Online (Sandbox Code Playgroud)
这会尝试PRINT_SIZE
使用两个参数(一个string{"ABCDEF"
和一个)来扩展宏,这两个参数3}
都会失败.在许多情况下(包括你的)可以通过添加另一对括号来解决这个问题:
PRINT_SIZE( (string{"ABCDEF",3}) );
Run Code Online (Sandbox Code Playgroud)
这些括号可以防止参数的分裂,因此可以PRINT_SIZE
使用单个参数进行扩展(string{"ABCDEF",3})
(请注意,括号是参数的一部分).
是的,有一个原因:预处理器不知道大括号.它只尊重字符串文字和括号,对其他C/C++语言结构它是无知的.就这样,电话
PRINT_SIZE( string{"ABCDEF",3} );
Run Code Online (Sandbox Code Playgroud)
被解析为具有两个参数的宏调用string{"ABCDEF"
和3}
.由于宏PRINT_SIZE()
只需要一个参数,因此预处理器可以解决问题.请注意,此时甚至没有调用C++编译器!
归档时间: |
|
查看次数: |
1553 次 |
最近记录: |