首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么不能在宏中使用C++11大括号初始化呢?

为什么不能在宏中使用C++11大括号初始化呢?
EN

Stack Overflow用户
提问于 2015-04-11 14:17:29
回答 3查看 2.9K关注 0票数 9

我刚刚发现,在将参数传递给宏时,不能总是使用大括号初始化。当ASSERT()宏编译失败时,我发现了这一点。然而,下面的示例说明了这个问题:

代码语言:javascript
复制
#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;
}

宏不能用于大括号初始化的原因吗?

编辑:

此后,我发现您也可以使用各种宏,这很好地解决了这个问题:

代码语言:javascript
复制
#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;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-11 14:21:31

列表被分成几个宏参数。当你写

代码语言:javascript
复制
PRINT_SIZE( string{"ABCDEF",3} );

这会尝试用两个参数展开宏PRINT_SIZE,一个是string{"ABCDEF",另一个是3},这两个参数都失败了。在许多情况下(包括您的情况),可以通过添加另一对括号来解决这一问题:

代码语言:javascript
复制
PRINT_SIZE( (string{"ABCDEF",3}) );

这些括号阻止了参数的分裂,从而使PRINT_SIZE用单个参数(string{"ABCDEF",3})展开(注意括号是参数的一部分)。

票数 16
EN

Stack Overflow用户

发布于 2015-04-11 14:22:21

是的,这是有原因的:预处理器不知道大括号。它只尊重字符串文字和括号,对其他C/C++语言结构则一无所知。因此,呼叫

代码语言:javascript
复制
PRINT_SIZE( string{"ABCDEF",3} );

被解析为具有两个参数string{"ABCDEF"3}的宏调用。由于宏PRINT_SIZE()只需要一个参数,所以预处理器就会退出。请注意,C++编译器此时甚至还没有被调用!

票数 8
EN

Stack Overflow用户

发布于 2021-05-29 15:26:59

这个怎么样?

代码语言:javascript
复制
#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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29578902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档