在C++中使用具有不同数量的参数的嵌套宏

Pre*_*Tiw 0 c++ macros c-preprocessor c++11

以下代码在g ++ -std = c ++ 11编译器的编译中失败.

    # 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;
    }
Run Code Online (Sandbox Code Playgroud)

1.为什么会这样?

2. C++预处理器实现者的实现问题是什么,他们避免了这个功能?

3.那我怎样才能使用这样的快捷方式?

H W*_*ers 5

你的两个选择是相同的.定义宏的顺序与它们的扩展无关; 它只与扩张时的定义相关.

为什么会这样?

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

可能是C++预处理器实现者的实现问题,他们避免了这个功能?

我认为你在这里做出了无根据的假设.问题不在于预处理器"缺少"某些"功能"; 这是你对预处理器如何工作的期望是错误的.

据推测,您希望预处理器执行以下操作:

  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步扩展.

问题是,这不是预处理器的工作方式.鉴于示例已被破坏,我无法用此正确说明这些步骤,因此我们假设我们这样做是为了说明目的:

#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)
Run Code Online (Sandbox Code Playgroud)

最后一行扩展为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

请注意,内部宏不会先扩展; 相反,外部宏.另请注意,此示例注入逗号; 所以注入一个逗号肯定是你可以实际做的事情,我认为这是你所指的那个被避免的"特征".

那我怎么能用这样的快捷方式?

鉴于预处理器不像您认为的那样工作,您可能不希望使用它来执行您认为要使用它的操作...即使对于速度编码也是如此. stlf很乐意为函数调用构建两个参数,但宏不是函数.似乎是你最好的选择.