传递可调用参数的约定

时间:2014-12-23 12:46:28

标签: c++ argument-passing

STL和其他地方的很多地方都会看到这样的代码:

template <typename Func>
void foo(Func f) 
{
      // ...
      f();
}

即。可调用参数f由值(副本)传递。为什么这似乎更倾向于将参数键入为Func&const Func&Func&&

1 个答案:

答案 0 :(得分:1)

简单的原因是您可以将推导类型的值转换为使用引用语义,例如,将std::ref(x)而不是x传递给函数。显然,对于比函数调用操作符更有趣的操作的东西,您可能需要使用自定义包装器,但一般来说,直接编写一个类的包装器,它为值类型提供引用语义。

另一方面,一旦您进入参考世界,就无法在调用者的控制下撤消此引用。接收对象引用的任何合理的泛型函数都不能假定此引用后面的对象实际上具有完全引用的类型,而是必须假设对象将被切片到它们的基类。因此,它不能通过复制将收到的参数(例如Func&)复制到Func

将这两个实现一起传递给推导类型的值是对于在通用函数的实现中可能被复制的实体的明显选择。请注意,这种推理通常适用于传递给泛型函数的参数,而不仅仅适用于可调用的参数。