template <typename T>
void func(T&){
}
int main(){
void (*p)(int&) = func;//or &func
return 0;
}
我想知道为什么这段代码会编译(使用g ++)。似乎模板函数的论证是从p的类型推导出来的?这是标准行为吗?
编辑: 我想出了一个可能的解释。该任务有签名:
void(*&)(int&)operator=(void(*)(int&));
因此func实际上是从operator =的输入参数类型推导出来的,而不是直接从 p 的类型推导出来的。这是对的吗?
答案 0 :(得分:29)
这是标准行为吗?
是的。当您获取函数模板的地址时(例如,在分配或初始化函数指针时执行),也会发生模板参数推导。它在[temp.deduct.funcaddr]/1中明确允许:
模板参数可以从拍摄时指定的类型推断出来 重载函数的地址。功能模板 函数类型和指定的类型用作P和A的类型, 扣除按照[temp.deduct.type]中的描述完成。
函数指针类型提供了上一段中的参数(A
)。
因此func实际上是从operator =的输入参数类型推导出来的,而不是直接从p的类型推导出来的。这是对的吗?
不是真的。首先,它不是赋值,它是你正在进行的初始化。即使它使用了重载的operator=
函数,你也需要推导来初始化赋值运算符的参数,这会让你回到原点。