C++中能否直接将函数作为参数传入另一函数?
你提供的代码本身是符合C++语法规范的,可以直接编译运行,输出结果为1 2 3 4 5 。
template <typename T, typename Func> void for_each(T* begin, T* end, const Func& f) { while (begin != end) f(*begin++); } template <typename T> void print(const T& x) { std::cout << x << " "; } int main() { int arr[5] = { 1, 2, 3, 4, 5 }; for_each(arr, arr + 5, print<int>); return 0; }
是否需要预先定义模板函数指针?
完全不需要。
此处的Func是模板参数,是对可调用对象的泛型抽象,只要传入的对象满足「可以接收一个T类型的参数进行调用」的要求,就能正常编译通过。它可以兼容普通函数、函数指针、lambda表达式、重载了operator()的仿函数等所有可调用类型。如果手动写死模板函数指针的签名,反而会把接口限制死,无法兼容仿函数、lambda这类更灵活的可调用对象。
是不是仅因为Func是泛型才支持该写法?
是的。
这种灵活性来自C++模板的鸭子类型特性:编译时只会检查传入的参数是否满足调用要求,不会强制定死参数的具体类型。如果不使用泛型模板,你要么需要为不同的参数类型、不同的可调用对象签名写多个for_each重载,要么只能硬写死固定签名的函数指针作为参数,灵活性会大幅降低。
代码中为什么要使用const和引用&?
分两处场景解释:
for_each函数的const Func& f参数
- 使用引用
&是为了避免可调用对象的拷贝开销:如果传入的是携带大量成员数据的仿函数,值传递会触发拷贝构造产生额外成本,引用可以直接复用原对象。 - 加
const一是保证f在for_each执行过程中不会被修改,符合语义;二是可以兼容const修饰的可调用对象,扩大接口的兼容范围。
print函数的const T& x参数
- 使用引用
&是为了避免传参的拷贝开销:如果T是大类型(比如自定义类、std::string、容器等),值传递会触发拷贝构造,性能损耗很高,引用可以直接访问原对象无需拷贝。 - 加
const一是保证print函数内部不会修改传入的x,符合打印操作只读的语义;二是支持传入const修饰的T类型对象,避免const对象传参时的编译错误。
内容的提问来源于stack exchange,提问作者Mac cchiatooo
相关产品推荐
相关产品推荐

