将函数的返回类型声明为 T&&& 是否毫无意义?
Is it meaningless to declare the return type of a function as T&&?
正如我们所知,在大多数情况下,T&&
的意思是"这是一个临时对象"。但是,如果要从函数返回临时对象,他/她可以按如下方式声明该函数:
template<class T>
T f()
{
T t;
......
return t;
}
或(注意:不正确)
template<class T>
T&& f()
{
T t;
......
return t;
}
但我认为后者过头了,因为前者已经足够了,而且向后兼容。
然而,我也发现std::forward()
的返回类型被声明为 T&&&,所以我确信我对此的理解是不完整的。
我真正的问题是:我们应该在何时何地将函数的返回类型声明为 T&&?
在你的例子中,T&&
是错误的,它是一个悬而未决的引用。
但是std::forward
不会在其自己的定义中返回对局部变量的右值引用,而是返回对其按值引用参数的右值引用(或对按值引用参数的左值引用)。
仅当希望函数的调用方能够从该引用的任何内容移动时,才应返回右值引用。
通常,只有当函数的目的是提供对某个重要对象(可能已经存在)的移动访问时,才会这样做。因此,这包括std::move
(它允许您从左值移动),类似地,您可以编写一个专门为用户设计的访问器函数,以便从某个对象的数据成员或某个容器的元素移动。如果对象本身不重要,只有值,则可以按值返回。
正如 grizzly 所说,有时由于引用折叠,您可以利用技巧,这意味着您在代码中键入T&&
,但是当T
已经是左值引用类型时T&&
是相同的左值引用类型。 std::forward
使用了这个技巧。也就是说,由于引用折叠T&&
并不意味着"对T的右值引用",它意味着"如果T是引用类型,则为T,否则对T的右值引用"。
T&&
并不一定意味着结果是右值。与模板参数一起使用时&&
表示通用引用,该引用可以是右值或左值引用。更具体地说:如果T
是左值引用类型foo&
,T&&
实际上是对foo
的左值引用,否则表示右值引用。
这可用于编写函数,这些函数接受任何类型的参数:
template<typename T> void foo(T&&);
bar a;
const bar b;
foo(a);//T and T&& will both be bar&
foo(b);//T and T&& will both be const bar&
foo(bar());//T will be bar, T&& will be bar&&
考虑到这一点std::forward
用一个T&
调用它并将其强制转换为T&&
,其中明确陈述了T
。因此,如果原始函数参数是左值引用,它将返回一个,否则它将返回一个右值引用,从而实现完美转发。
至于何时将其用作返回类型: 很少,尽管在传递参数时避免复制可能很有用,例如:
template<typename T> T&& foo(T&& bar) {/*some ops*/ return std::forward<T>(bar);}
答案取决于您的函数是否是模板函数。在你的问题中是,但让我们先看看它是否不是:
非模板
T&&
作为返回类型并非毫无意义。原因是它实际上并不意味着"临时对象"。它的意思是"右值引用"。差异是微妙的,但可以使用与此返回类型相关的一类函数突出显示。也就是说,如果我们想返回对右值的引用,但它引用的对象不是我们函数的本地对象怎么办?
T&& return_rvalue(/*some data*/)
{
T&& t = Get_a_reference();
// Do something fascinating.
return static_cast<T&&>(t);
}
这种模式的一个非常特殊的情况是函数std::move
,它接受任何引用并返回相应的右值引用。当然,在实际代码中,您当然应该使用std::move
而不是直接执行强制转换,因为这更清楚地表明了您的意图。
模板
如果T
是模板参数,则T&&
Scott Meyers 所说的通用引用。这意味着T&&
的类型将使用参考折叠来计算出来......简而言之,这意味着如果 T
i 不是引用类型,则T&&
是右值,如果是,则为左值引用。
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- API 返回智能指针的 std::optional 以明确指定指针可能为 null 是否有意义?
- 从头开始为应用程序创建 docker 映像是否有意义?
- 函数重载毫无意义吗
- x86 - 为什么编译器在下一条指令中插入看似毫无意义的JMP?
- 插入向量时,使用lambda的返回而不是函数的返回是否有意义?
- OpenGL 中的动态加载着色器毫无意义吗?
- 将 final 关键字添加到没有基类(未派生)的类中的虚函数是否有意义
- 左移负整数为零是否有意义?
- 如果编译器只能执行恒定折叠,则是毫无意义的
- 将可选与reference_wrapper相结合是否有意义?
- 函数返回rvalue参考是否有意义
- 将 [[noreturn]] 添加到主函数是否有意义
- 在shared_ptr的自定义删除器中检查 nullptr 是否有意义?
- 拥有一个没有构造函数的类是否有意义
- 在同一调用中打印 %n 的值 - 毫无意义?
- 这是否有意义,我的计算机只能并行运行4个线程
- constexpr移动构造函数是否有意义
- Netbeans 中的C++:许多毫无意义的"unexpected token"提示
- 将函数的返回类型声明为 T&&& 是否毫无意义?