std :: forward如何接收正确的参数?

模板男孩

考虑:

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

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

int main()
{
    f(10);
}

由于id表达式x是一个左值,并且std::forward具有左值和右值的重载,为什么调用不绑定到该std::forward的重载就需要一个左值?

template<class T>
constexpr T&& forward(std::remove_reference_t<T>& t) noexcept;
霍华德·辛南特

确实绑定了std::forward采用左值的重载

template <class T>
constexpr T&& forward(remove_reference_t<T>& t) noexcept;

它与绑定T == int指定此函数以返回:

static_cast<T&&>(t)

因为Tf推论到int因此,此重载将lvalue转换int为xvalue:

static_cast<int&&>(t)

因此称为g(int&&)超载。

总而言之,of的左值重载std::forward可以将其参数转换为左值或右值,这取决于T调用它的类型

的rvalue重载std::forward只能转换为rvalue。如果尝试调用该重载并将其强制转换为左值,则程序的格式不正确(需要编译时错误)。

所以重载1:

template <class T>
constexpr T&& forward(remove_reference_t<T>& t) noexcept;

捕获左值。

重载2:

template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;

捕获右值(即xvalue和prvalue)。

重载1可以将其左值参数强制转换为左值或xvalue(出于重载解析的目的,后者将被解释为右值)。

重载2只能将其rvalue参数强制转换为xvalue(出于重载解析目的,它将被解释为rvalue)。

对于N2951中标记为“ B.应该将右值作为右值转发”的情况,过载2 简而言之,这种情况可以实现:

std::forward<T>(u.get());

在不确定是否u.get()返回左值或右值的情况下,但是如果T不是左值引用类型,无论哪种方式,都希望移动返回的值。但是您不使用,std::move因为如果T 左值引用类型,则您希望从返回值中移出。

我知道这听起来有些人为。但是,N2951在设置激励用例方面遇到了很大的麻烦,这些用例对于std::forward显式提供的模板参数和隐式提供的普通参数的表达类别的所有组合应如何表现。

这不是一个容易阅读,但对于模板和普通参数的每个组合的理由std::forwardN2951当时这在委员会上是有争议的,而不是一件容易的事。

N2951的最终形式std::forward不完全是N2951提出的形式。但是,它确实通过了N2951中提出的所有六项测试

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章