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.那我怎样才能使用这样的快捷方式?
你的两个选择是相同的.定义宏的顺序与它们的扩展无关; 它只与扩张时的定义相关.
为什么会这样?
您正在repf使用两个参数调用宏,但它需要三个参数.这是一个错误,简单明了,因此预处理失败了.
可能是C++预处理器实现者的实现问题,他们避免了这个功能?
我认为你在这里做出了无根据的假设.问题不在于预处理器"缺少"某些"功能"; 这是你对预处理器如何工作的期望是错误的.
据推测,您希望预处理器执行以下操作:
repf(arr, stlf(arr))repf(arr, arr.begin(), arr.end())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,它更像这样:
FOO(ACOMMAB, C)BAR(ACOMMAB, C)BAR(A, B, C)x is A y is B c is Z请注意,内部宏不会先扩展; 相反,外部宏.另请注意,此示例注入逗号; 所以注入一个逗号肯定是你可以实际做的事情,我认为这是你所指的那个被避免的"特征".
那我怎么能用这样的快捷方式?
鉴于预处理器不像您认为的那样工作,您可能不希望使用它来执行您认为要使用它的操作...即使对于速度编码也是如此. stlf很乐意为函数调用构建两个参数,但宏不是函数.似乎是你最好的选择.