为什么宏扩展遵循模板扩展?

xml*_*lmx 1 c++ templates c-preprocessor

通常,代码示例首先:

void f1(int)
{}

#define f2(a) f1(a)

template<class F>
void f3(F f)
{
    f(0);
}

int main()
{
    f3(f2); // error C2065: 'f2' : undeclared identifier
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

由VC++ 2012编译.

我的问题是:

为什么宏扩展遵循模板扩展?我认为这是极端反直觉和容易出错的.

小智 8

为什么宏扩展遵循模板扩展?

嗯,它没有.宏扩展由预处理器完成,模板扩展由解析器/编译器阶段完成(仅预处理运行).

你在这里缺少的是宏的风格.f2()是一个函数式宏.因此,如果您编写f2(没有括号),预处理器将不会替换它f1.如果您想要这样的替换,只需将其定义为

#define f2 f1
Run Code Online (Sandbox Code Playgroud)

旁注:就目前而言,这段代码没有多大意义.即使您使用括号并写入f2(),也会出现编译器错误,因为f2()宏只接受一个参数.如果它是一个具有参数且不是可变参数的函数式宏,则应该为它提供一个参数.