繁体   English   中英

在c ++中使用std :: forward

[英]Use of std::forward in c++

我遇到过一个代码,其中使用了std::forward 我已经搜索了很长时间,并且无法理解它的真实目的和用途。

我在stackoverflow中看到了类似的线程,但仍然不清楚。 有人可以用一个简单的例子解释一下吗?

PS:我已经浏览了这个页面 ,但仍然无法欣赏它的使用。 请不要将此问题标记为重复,而是尝试帮助我。

当你链接的页面构成它:

这是一个辅助函数,可以完美地转发作为对推导类型的rvalue引用的参数,保留所涉及的任何潜在的移动语义。

当你有一个命名值时 ,如

void f1(int& namedValue){
    ...
}

或者在

void f2(int&& namedValue){
    ...
}

无论如何,它都会评估 lvalue

更进一步。 假设你有一个模板功能

template <typename T>
void f(T&& namedValue){
    ...
}

这样的函数可以用左值或右值调用; 但是,无论如何,namedValue都会评估为lvalue

现在假设您有两个辅助函数重载

void helper(int& i){
    ...
}
void helper(int&& i){
    ...
}

f里面调用helper

template <typename T>
void f(T&& namedValue){
    helper(namedValue);
}

将总是调用helper的第一个重载,因为namedValue一个命名值 ,当然,它会计算为lvalue

为了在适当的时候调用第二个版本(即当用rvalue参数调用f时),你写

template <typename T>
void f(T&& namedValue){
    helper( std::forward<T>(namedValue) );
}

以下所有这些都在文档中非常简明扼要地表达出来

对这个函数的需求源于这样一个事实,即所有命名值(例如函数参数)总是作为左值(甚至是那些被声明为右值引用的值)进行评估,这在保留模板函数上的潜在移动语义方面存在困难,模板函数将参数转发给其他函数。

每个表达式恰好是以下两个值类别之一:左值或右值。

通常,如果你调用如下函数:

template<typename T>
void f(T t);

template<typename T>
void g(T t)
{
    f(t);
}

g的参数的值类别在调用g和f之间丢失,因为命名参数(如局部变量)总是lvalues。

通过使用std::forward并将参数调整为使用引用折叠的“通用引用”,您可以保留值类别:

template<typename T>
void f(T&& t);

template<typename T>
void g(T&& t)
{
    f(forward<T>(t));
}

这就是为什么它被称为“前进”,因为你正在“转发”价值类别,而不是失去它。

因此,在示例中,如果使用rvalue调用g ,则将使用rvalue调用f - 而不是左值。

它用于在将模板传递给另一个函数时保留模板中参数的确切类型。 例如:

template<class T>
void wrapper(T&& arg)
{
    foo(std::forward<T>(arg)); // Forward a single argument.
}

其工作原理如下:

  • 如果函数wrapper获取std::stringconst std::string& ,则调用foo就好像arg具有const std::string&

  • 如果函数wrapper获取std::string& ,则调用foo就好像arg具有std::string&类型一样。

  • 如果函数wrapper获取std::string&& ,则调用foo就好像arg具有std::string&&类型。

std::forward解决的问题是通过常规规则,函数中的arg类型是std::string即使我们将std::string&&传递给wrapper std::forward允许向调用站点注入实际类型的T ,即TT&const T&T&&

它的基本用途是你在函数g中被称为这样:

g(T1 p1, T2 p2, /* ... */);

并且您想要使用完全相同的类型调用函数f

f(T1 p1, T2 p2, /* ... */);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM