但是我的程序崩溃了,编译器告诉我我错过了一个没有意义的参数,因为我的函数是一元而不是二元运算
您应该清楚地说明您的程序是否编译然后崩溃,而不是编译,编译器崩溃以及缺少什么类型的参数。
现在猜猜你的意思,问题是transform
模板没有对最后一个参数施加任何限制,因此编译器无法确定reciprocal
应该将哪些重载(特化)传递给转换模板。您可以手动指定您想要的:
transform(vec.begin(), vec.end(), vec.begin(), &reciprocal<int>);
或者可以禁止使用带有转换的模板?
这本身就是一个有趣的观点,因为它显示了一些常见的误解。Atemplate
是创建其他元素的蓝图。在这种情况下,您有一个函数模板,它只是一个蓝图,编译器将通过替换模板参数从中生成不同的函数。在需要函数的任何上下文中,都不能使用函数模板,尽管可以使用专门化(即从该函数模板生成的函数)。
在某些情况下,您可以使用模板的名称来引用具体的特化,这会变得有些混乱。也就是说,在类模板定义(或它的成员的定义)中,模板的名称可以用来指代特化。在函数模板的情况下,模板的名称可用于在编译器能够丢弃除其中一种特化之外的所有特化的上下文中引用函数模板的所有可能特化,例如:
int call(int (*ptr)(int)) { return ptr(5); }
call(reciprocal); // [1]
在 [1] 中,reciprocal
指的是函数模板的所有可能的特化,但这种特殊用途是允许的,因为这些特化中只有一个(即)可以用作 的参数。reciprocal<int>
call
但这些是例外,主要的一点是类模板或函数模板不是类或函数,而是编译器可以从中创建类和函数的生成器。