std :: forward是否有prvalue的用例? [英] Are there any use cases for std::forward with a prvalue?

查看:181
本文介绍了std :: forward是否有prvalue的用例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

std :: forward 的最常见用法是完美转发转发(通用)引用,例如

The most common usage of std::forward is to, well, perfect forward a forwarding (universal) reference, like

template<typename T>
void f(T&& param)
{
    g(std::forward<T>(param)); // perfect forward to g
}

这里 param 是一个 lvalue ,和 std :: forward 结束了它转换为右值或左值,

Here param is an lvalue, and std::forward ends up casting it to a rvalue or lvalue, depending on what the argument that bounded to it was.

查看右值 std :: forward / code> overload

Looking at the definition of std::forward from cppreference.com I see that there is also a rvalue overload

template< class T >
T&& forward( typename std::remove_reference<T>::type&& t );

任何人都可以告诉我为什么 rvalue 过载?我看不到任何用例。如果你想传递一个右值到一个函数,你可以直接传递它,不需要应用 std :: forward

Can anyone give me any reason why the rvalue overload? I cannot see any use case. If you want to pass a rvalue to a function, you can just pass it as is, no need to apply std::forward on it.

这不同于 std :: move ,我看到为什么还想要一个 rvalue overload:你可以处理一般的代码,你不知道你是什么,你想要无条件支持移动语义,见例如为什么std :: move采用通用引用?

This is different from std::move, where I see why one wants also a rvalue overload: you may deal with generic code in which you don't know what you're being passed and you want unconditional support for move semantics, see e.g. Why does std::move take a universal reference?.

EDIT 要澄清问题,我要问为什么超载( 2)从这里是必要的,以及一个用例。

EDIT To clarify the question, I'm asking why overload (2) from here is necessary, and a use case for it.

推荐答案

确定,因为@vsoftco要求简明使用案例在这里是一个精致的版本(使用他的想法有my_forward实际上看到wich重载被调用)。

Ok since @vsoftco asked for concise use case here's a refined version (using his idea of having "my_forward" to actually see wich overload gets called).

我解释用例通过提供代码示例没有prvalue没有编译或行为不同(不管那将是真正有用或不)。

I interpret "use case" by providing a code sample that without prvalue not compile or behave differently (regardless of that would be really usefull or not).

我们有 2重载 std :: forward

#include <iostream>

template <class T>
inline T&& my_forward(typename std::remove_reference<T>::type& t) noexcept
{
    std::cout<<"overload 1"<<std::endl;
    return static_cast<T&&>(t);
}

template <class T>
inline T&& my_forward(typename std::remove_reference<T>::type&& t) noexcept
{
    std::cout<<"overload 2"<<std::endl;
    static_assert(!std::is_lvalue_reference<T>::value,
              "Can not forward an rvalue as an lvalue.");
    return static_cast<T&&>(t);
}

我们有4种可能的用例

使用案例1

#include <vector>
using namespace std;

class Library
{
    vector<int> b;
public:
    // &&
    Library( vector<int>&& a):b(std::move(a)){

    }
};

int main() 
{
    vector<int> v;
    v.push_back(1);
    Library a( my_forward<vector<int>>(v)); // &
    return 0;
}

使用案例2
$ b

Use case 2

#include <vector>
using namespace std;

class Library
{
    vector<int> b;
public:
    // &&
    Library( vector<int>&& a):b(std::move(a)){

    }
};

int main() 
{
    vector<int> v;
    v.push_back(1);
    Library a( my_forward<vector<int>>(std::move(v))); //&&
    return 0;
}

用例3

#include <vector>
using namespace std;

class Library
{
    vector<int> b;
public:
    // &
    Library( vector<int> a):b(a){

    }
};

int main() 
{
    vector<int> v;
    v.push_back(1);
    Library a( my_forward<vector<int>>(v)); // &
    return 0;
}

使用案例4

#include <vector>
using namespace std;

class Library
{
    vector<int> b;
public:
    // &
    Library( vector<int> a):b(a){

    }
};

int main() 
{
    vector<int> v;
    v.push_back(1);
    Library a( my_forward<vector<int>>(std::move(v))); //&&
    return 0;
}

以下是简历


  1. 使用重载1,不会出现编译错误

  2. 使用重载2,编译错误

  3. 使用重载1,wihtout它会导致编译错误

  4. 使用重载2,

  1. Overload 1 is used, without it you get compilation error
  2. Overload 2 is used, without it you get compilation error
  3. Overload 1 is used, wihtout it you get compilation error
  4. Overload 2 is used, without it you get compilation error






请注意,如果我们不使用转发


Note that if we do not use forward

Library a( std::move(v));
//and
Library a( v);

您会得到:


  1. 编译错误

  2. 编译

  3. 编译

  4. Compile

  1. Compilation error
  2. Compile
  3. Compile
  4. Compile

正如你所看到的,如果你只使用两个 code>重载,你基本上导致不编译2的4个案例,而如果你不使用 forward 在所有你会得到只编译3 4例。

As you see, if you use only one of the two forward overloads, you basically cause to not compile 2 out of 4 cases, while if you do not use forward at all you would get to compile only 3 out of 4 cases.

这篇关于std :: forward是否有prvalue的用例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆