C++11 模板方法中可调用对象的最佳类型是什么?

C++11 模板方法中可调用对象的最佳类型是什么?,c++11,templates,lambda,callable,C++11,Templates,Lambda,Callable,每次我编写一个接受模板化可调用的签名时,我总是想知道参数的最佳类型是什么。它应该是值类型还是常量引用类型 比如说, template <class Func> void execute_func(Func func) { /* ... */ } // vs. template <class Func> void execute_func(const Func& func) { /* ... */ } 模板 无效执行函数(func func){

每次我编写一个接受模板化可调用的签名时,我总是想知道参数的最佳类型是什么。它应该是值类型还是常量引用类型

比如说,

template <class Func>
void execute_func(Func func) {
    /* ... */
}

// vs.

template <class Func>
void execute_func(const Func& func) {
    /* ... */
}
模板
无效执行函数(func func){
/* ... */
}
//vs。
模板
无效执行函数(常量函数和函数){
/* ... */
}
是否存在可调用大于64位(即指向func的指针)的情况?也许
std::function
的行为有所不同

是否存在可调用值大于64位的情况


根据我在CAD/CAE应用程序方面的工作经验,很多。函子可以轻松保存大于64位的数据。在Visual Studio中,超过该限制只需两个以上的
int
s、一个以上的
double
、一个以上的指针即可。

没有最佳类型。如果你有不可复制的函子呢?第一个模板将无法工作,因为它将尝试使用已删除的副本构造函数。您必须移动它,但随后您将失去(可能)对象的所有权。这完全取决于预期用途。是的,std::function可以比size\u t大很多。如果绑定成员函数,它已经是2个字(对象指针和函数指针)。如果你约束一些论点,它可能会进一步发展。lambda也是一样,每个捕获的值都存储在lambda中,在本例中,lambda基本上是一个函子。如果您的可调用对象具有非常量运算符,常量引用将不起作用。它们都不是所有用途的完美之选。有时,最好的选择是提供几个不同的版本,以便您可以处理所有情况,SFINAE是您在这里的朋友。

通常,我不喜欢通过常量引用传递
可调用的对象,因为它没有那么灵活(例如,它不能用于可变lambda)。我建议按价值传递它们。如果您检查stl算法实现(例如,对于
std::for_each
),所有可调用对象也会按值传递


如果需要,用户仍然可以使用
std::ref(func)
std::cref(func)
来避免不必要地复制可调用对象(使用
reference\u wrapper

“没有任何捕获的lambda是函数指针。带有捕获(闭包)的lambda仍然是其运算符()常量的地址。”不正确:Thx,我不知道。有意义。遵循标准的习语总是一个好主意。泰。