相关疑难解决方法(0)

std :: forward()的右值引用重载的目的是什么?

我正在尝试完美转发,发现 std::forward()需要两个重载:

过载 1:

template <typename T>
inline T&& forward(typename 
std::remove_reference<T>::type& t) noexcept
{
    return static_cast<T&&>(t);
}
Run Code Online (Sandbox Code Playgroud)

重载nr.2:

template <typename T>
inline T&& forward(typename 
std::remove_reference<T>::type&& t) noexcept
{
    static_assert(!std::is_lvalue_reference<T>::value,
              "Can not forward an rvalue as an lvalue.");
    return static_cast<T&&>(t);
}
Run Code Online (Sandbox Code Playgroud)

现在,完美转发的典型场景是

template <typename T>
void wrapper(T&& e)
{
    wrapped(forward<T>(e));
}
Run Code Online (Sandbox Code Playgroud)

当然,您知道何时wrapper()实例化T取决于传递给它的参数是左值还是右值。如果它是type的左值UT则推导为U&。如果是右值,T则推导为U

无论如何-在-的范围内wrapper()- e是一个左值,因此它始终使用的第一个重载std::forward()

现在我的问题是:

使用(需要)第二重载的有效方案是什么?

c++ perfect-forwarding c++11 c++14 c++17

16
推荐指数
1
解决办法
409
查看次数

std :: forward如何获得正确的参数?

考虑:

void g(int&);
void g(int&&);

template<class T>
void f(T&& x)
{
    g(std::forward<T>(x));
}

int main()
{
    f(10);
}
Run Code Online (Sandbox Code Playgroud)

由于id-expression x是一个左值,并且std::forward对于左值和右值有重载,为什么调用不能绑定到std::forward需要左值的重载?

template<class T>
constexpr T&& forward(std::remove_reference_t<T>& t) noexcept;
Run Code Online (Sandbox Code Playgroud)

c++ templates rvalue-reference perfect-forwarding c++11

12
推荐指数
2
解决办法
1052
查看次数

为什么不`const int ci = 2; std :: forward <int>(ci);`工作以及如何修复/解决它?

简单的问题,为什么不做以下工作(暗示副本ci)?

#include <utility>

int main(){
  const int ci = 2;
  std::forward<int>(ci);
}
Run Code Online (Sandbox Code Playgroud)

prog.cpp:在函数'int main()'中:
prog.cpp:6:23:错误:没有用于调用'forward(const int&)'的匹配函数

在编写一些模板内容时,问题就出现了,我有一个简单的持有者类型,如下所示.为了避免不必要的副本,我尽可能使用完美转发,但结果证明它似乎是问题的根源.

template<class T>
struct holder{
    T value;

    holder(T&& val)
        : value(std::forward<T>(val))
    {}
};

template<class T>
holder<T> hold(T&& val){
    // T will be deduced as int, because literal `5` is a prvalue
    // which can be bound to `int&&`
    return holder<T>(std::forward<T>(val));
}

template<class T>
void foo(holder<T> const& h)
{
    std::tuple<T> t;  // contrived, actual function takes more parameters
    std::get<0>(t) = std::forward<T>(h.value); …
Run Code Online (Sandbox Code Playgroud)

c++ perfect-forwarding c++11

9
推荐指数
1
解决办法
3088
查看次数

为什么std :: forward有两个签名?

cplusplus.com所述,std::forward有两个签名:

template <class T> T&& forward (typename remove_reference<T>::type& arg) noexcept;
template <class T> T&& forward (typename remove_reference<T>::type&& arg) noexcept;
Run Code Online (Sandbox Code Playgroud)

典型的用法std::forward是在将参数传递给其他函数时保留rvalueness.让我们用一个例子来说明这一点:

void overloaded(int &)  { std::cout << "lvalue"; }
void overloaded(int &&) { std::cout << "rvalue"; }

template <typename T>
void fwd(T && t)
{
  overloaded(std::forward<T>(t));
}
Run Code Online (Sandbox Code Playgroud)

当我们打电话时fwd(0),T推断为int(t有类型int &&).然后我们打电话std::forward<int>(t).该调用的结果是类型的表达式,int &&因此选择了第二个overloaded函数版本,程序将"rvalue"打印到标准输出.

当我们调用fwd(i)(其中我是一些int变量)时,T推导为int&(t有类型 …

c++ stl rvalue rvalue-reference c++11

5
推荐指数
1
解决办法
324
查看次数