1

通常,代码示例首先:

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;
}

由 VC++ 2012 编译。

我的问题是:

为什么宏扩展跟随模板扩展?我认为这是非常违反直觉且容易出错的。

4

2 回答 2

8

为什么宏扩展跟随模板扩展?

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

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

#define f2 f1

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

于 2012-11-16T21:54:19.650 回答
4

它没有。

问题是您已经f2使用函数式宏定义进行了定义,例如

#define f2(foo) bar

但是在您的源代码中,您仅将f2其用作令牌,而不是将其用作函数调用,例如

f3(f2)

由于您没有将它用作函数调用,因此它与函数样式的宏定义不匹配,因此不会被替换。

于 2012-11-16T21:54:21.787 回答