在C ++中将嵌套宏与不同数量的参数一起使用 [英] Using nested macro with different number of arguments in C++

查看:139
本文介绍了在C ++中将嵌套宏与不同数量的参数一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码无法通过g ++ -std = c ++ 11编译器进行编译.

The following code fails in compilation by g++ -std=c++11 compiler.

    # include<iostream>
    # include<vector>

    using namespace std;


    # define stlf(x)        x.begin(), x.end()
    # define repf(it, a, b) for(auto it = a ; it != b ; ++it)


    /*
    // Also, following alternative fails

    # define repf(it, a, b) for(auto it = a ; it != b ; ++it)
    # define stlf(x)        x.begin(), x.end()

    */



    typedef vector<int > vi;

    # define pd(x)  printf("%d", x);

    int main(void){

        vi arr(10, -1);

        repf(arr, stlf(arr))
            pd(arr[i]);


        return 0;
    }

1..为什么会发生这种情况?

1. Why is this happening ?

2..对于C ++ Pre-Processor实现者,他们可能避免了此功能,这可能是实现问题吗?

2. What could have been implementation problem for C++ Pre-Processor implementors, that they avoided this feature ?

3..然后如何使用此类快捷方式??

3. How can I then use such shortcuts ??

推荐答案

您的两个选择是相同的.宏的定义顺序与扩展无关.仅与扩展时定义的内容相关.

Your two alternatives are identical. The order that macros are defined in is irrelevant to their expansion; it's only relevant what they are defined as at the time of expansion.

为什么会这样?

您正在使用两个参数调用宏repf,但是它需要三个参数.这是一个简单明了的错误,因此预处理失败.

You're invoking the macro repf with two arguments, but it takes three arguments. That is an error, plain and simple, so preprocessing fails.

对于C ++预处理程序实现者来说,他们可能会避免此功能,这可能是实现问题吗?
What could have been implementation problem for C++ Pre-Processor implementors, that they avoided this feature ?

我认为您在这里做一个毫无根据的假设.问题不在于预处理器缺乏"某些功能";那是您对预处理器工作方式的期望是错误的.

I think you're making an unwarranted assumption here. The issue isn't that the preprocessor "lacks" some "feature"; it's that your expectations of how the preprocessor works is wrong.

大概,您希望预处理器执行以下操作:

Presumably, you expect the preprocessor to do something like this:

  1. repf(arr, stlf(arr))
  2. repf(arr, arr.begin(), arr.end())
  3. for(auto it = arr.begin() ; it != arr.end() ; ++it)
  1. repf(arr, stlf(arr))
  2. repf(arr, arr.begin(), arr.end())
  3. for(auto it = arr.begin() ; it != arr.end() ; ++it)

...从步骤1到步骤2,stlf(arr)展开;然后将其扩展放入对repf的调用中,然后在步骤3中对其进行扩展.

...where from step 1 to step 2, stlf(arr) gets expanded; then its expansion is put into the call to repf, which then gets expanded at step 3.

问题是,预处理器不是这样工作的.鉴于该示例已损坏,因此我无法用此示例正确地说明步骤,所以让我们假设这样做是出于说明的目的:

The problem is, that is not how the preprocessor works. Given the example is broken, I can't illustrate the steps properly with this, so let's suppose we do this instead for illustration purposes:

#define FOO(X, Y) BAR(X, Y)
#define BAR(X,Y,Z) x is X y is Y z is Z
#define ACOMMAB A, B
FOO(ACOMMAB, C)

最后一行扩展到x is A y is B c is Z,其工作方式如下:

That last line expands to x is A y is B c is Z, and it works more like this:

  1. FOO(ACOMMAB, C)
  2. BAR(ACOMMAB, C)
  3. BAR(A, B, C)
  4. x is A y is B c is Z
  1. FOO(ACOMMAB, C)
  2. BAR(ACOMMAB, C)
  3. BAR(A, B, C)
  4. x is A y is B c is Z

请注意,内部宏不会先展开;而是外部宏起作用.另请注意,此示例注入了逗号.因此注入逗号绝对是您实际上可以做的事情,我认为这是您所避免的功能".

Note that the inner macro doesn't expand first; rather, the outer macro does. Note also that this example injects a comma; so injecting a comma is definitely something you can in fact do, which I assume to be the "feature" you refer to that was avoided.

然后如何使用此类快捷方式?
How can I then use such shortcuts ??

鉴于预处理器不能像您认为的那样工作,您可能不想使用它来做您想使用的东西...甚至用于速度编码. stlf将很乐意为您创建两个用于函数调用的参数,但是宏不是函数.放浪似乎是您最好的选择.

Given the preprocessor doesn't work the way you think it does, you probably don't want to use it to do what you think you want to use it to do... even for speed coding. stlf will gladly build two arguments for you for function calls, but macros are not functions. Ranged for seems to be your best bet.

这篇关于在C ++中将嵌套宏与不同数量的参数一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆