【发布时间】:2019-07-25 10:40:28
【问题描述】:
我认为带有通用引用参数的构造函数比没有引用的构造函数性能更好。
从 cppreference (https://en.cppreference.com/w/cpp/utility/functional/function/function) 中,我们可以看到 std::function 的模板构造函数没有使用引用。
template< class F > function( F f );
这是一个错误吗?如果不是,为什么标准不要求构造函数使用通用引用?
编辑:
让我们考虑两种情况。
- F是一个内置类型,这里是一个大小为4字节的函数指针。
使用通用参考:
左值情况:复制4个字节。
右值情况:复制 4 个字节。 (你会将std::move 应用于内置类型吗?)
按值传递:
所有情况:复制 4 个字节。
- F 是具有非平凡复制构造函数的类型,例如。一个 lambda 类型,它按值捕获
std::string。这个例子代表了大多数情况,你同意吗?
使用通用参考:
左值案例:复制构造函数被调用一次
右值案例:移动构造函数被调用一次
按值传递:
左值案例:移动和复制
右值案例:移动
这个分类是否完整?如果是这样,我们可以得出结论,通用引用并不比按值传递更糟糕。然后回到原来的问题。
再次编辑:
也许没有捕获的 lambda 是最常见的情况,其中按值传递实际上是什么都不传递,而按引用传递是传递一个指针。这可能是关键。 LWG 2774 与这个问题有关。在 cmets 中查看。
【问题讨论】:
-
在这个问题 (stackoverflow.com/questions/21605579/…) 中,我评论说 const 左值引用和右值引用构造函数一起提供了与非引用构造函数相同的性能。既然通用引用可以处理左值和右值引用,为什么不使用它呢?
-
指定从
move(f)构造。所以没有副本。 -
"我评论说 const 左值引用和右值引用构造函数一起提供了至少与非引用构造函数相同的性能" - 你以
std::string为例.它不一定适用于每种类型。 -
@L.F.参数
f上是否使用move与f的初始化是否涉及复制构造无关。 -
这是LWG 2774。