何时从非模板和非成员函数返回 T&&
When to return T&& from a non-template and non-member function
请注意,之前有关于模板函数或成员函数的答案,但这个问题只是关于非模板非成员函数。 std::move() 返回 T&&,例如,它是一个模板函数。
是否有充分的理由将 T&& 用作非模板和非成员函数的返回类型,其中 T 是任意类型?
例如,您什么时候会使用以下?
T&& fn()
{
....
return ....
}
我见过使用它的示例,但在所有示例中,开发人员误解了移动语义,应该按值返回并利用 NRVO。
假设我们有一个粒子系统。我们希望将其实现为粒子池。这意味着我们将希望一遍又一遍地回收相同的粒子,因此要重用资源,我们将需要传递右值。
现在,假设我们的粒子的生命周期非常短,但我们希望在它们"过期"时发生一些事情(例如增加整数x
),但我们仍然想回收它们。现在,假设我们希望能够指定 x
.但是,现在我们该怎么办?
在移动中,我们希望能够调用一个函数来递增一个变量,但该变量必须波动。我们不想把它放到析构函数中,因为这将涉及在编译时派生确切函数调用的模板,或者我们需要一个std::function
或函数指针来从粒子内部引用函数,浪费空间。我们想要做的是能够接收即将过期的值,执行操作,然后转发它。 换句话说,我们想要一个有副作用的向外移动,特别是从左值到右值的转换。
你执行哪个动作确实很重要 - 在左值到右值转换或接收到另一个具有operator=
或operator()
的粒子时。要么在对象收到值时执行此操作,要么在获取右值时执行此操作。但是假设我们想为许多不同类型的对象执行此操作 - 您是否要为 5 个不同类中的每一个编写 5 个或更多不同的移动函数,或者我们应该使用外部模板化函数对这些类型进行参数化?
不然你会怎么做?您仍然会使用对象内部的std::move()
,但我们希望将其与对象外部的函数耦合,因为这将表示移动的副作用。
科利鲁: http://coliru.stacked-crooked.com/a/0ff11890c16f1621
#include <iostream>
#include <string>
struct Particle {
int i;
};
template <typename T>
T&& move( T& obj, int (*fn)(int) , int& i ) {
i = fn(i);
return(std::move(obj));
}
int increment(int i) { return i+1; }
int main() {
// Have some object pool we want to optimize by moving instead of creating new ones.
// We'll use rvalue semantics so we can "inherit" lifetime instead of copying.
Particle pool[2000];
// Fill up the "particles".
for (auto i = 0; i < 2000; ++i) {
pool[i].i = i;
}
// Perform the moves with side effects.
int j = 0;
for (auto i = 0; i < 1999; ++i) {
pool[i+1] = move<Particle>(pool[i], &increment, j);
std::cout << "Moves performed: " << j << 'n';
}
}
有时,有一个将*this
作为 l 值引用返回的方法会很方便,这样您就可以将临时传递给接受 l 值引用的函数。
func(foo_t().lval_ref());
那么,人们为什么要这样做呢?假设一个函数将 l 值引用作为输出变量。如果调用者实际上不需要此输出,则传递一个临时变量而不是定义一些虚拟变量unused
会很方便,然后static_cast<void>(unused);
来抑制任何未使用变量的警告。
同样,可能希望有一个将*this
作为 r 值引用返回的方法,该方法的使用方式与 std::move()
相同。这样做可以为您提供更大的灵活性。您可以在方法实现中做任何您想要的棘手事情:-)
- 从函数返回const char*数组
- 检查函数返回类型是否与STL容器类型值相同
- 从 c 或 cpp 系列子函数返回到主函数
- 从函数返回任意简单类型的数据
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 从 C++ 中的函数返回数组地址问题
- VirtDisk.h QueryChangesVirtualDisk() 函数返回 RangeCount 为 0
- 为什么glGetSubroutineIndex为不同的函数返回相同的值?
- 在 c++ 中将函数返回类型指定为模板参数
- 从封装在对象中的函数 C++ 返回时为空的列表
- 为什么向量内部的指针在从函数返回时会发生变化?
- 函数返回的 rvalue 引用(表达式)是 xvalue - 但没有标识?
- 程序中的布尔函数返回输入的范围无论如何都是无效的
- 寿命延长从函数返回引用
- 程序不向函数返回值
- 字符串函数返回奇怪的值
- 类的大问题,以及从空函数c++返回
- 为什么在尝试测量函数返回所需的时间时,我的运行时编号是错误的?
- C++二叉搜索树模板从函数返回节点
- NVCC 错误:string_view.h:constexpr 函数返回是非常量