gpt4 book ai didi

c++ - 为什么使用 std::forward 禁用模板参数推导?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:53:03 27 4
gpt4 key购买 nike

在 VS2010 中,std::forward 定义如下:

template<class _Ty> inline
_Ty&& forward(typename identity<_Ty>::type& _Arg)
{ // forward _Arg, given explicitly specified type parameter
return ((_Ty&&)_Arg);
}

identity 似乎仅用于禁用模板参数推导。在这种情况下有意禁用它有什么意义?

最佳答案

如果将右值引用传递给 X 类型的对象到采用类型 T&& 的模板函数作为其参数,模板参数推导推导 T成为X .因此,该参数的类型为 X&& .如果函数参数是左值或 const 左值,则编译器将其类型推断为该类型的左值引用或 const 左值引用。

如果std::forward使用的模板参数推导:

objects with names are lvalues唯一一次std::forward会正确转换为 T&&当输入参数是一个未命名的右值时(如 7func() )。在完美转发的情况下arg你传递给std::forward是一个左值,因为它有一个名字。 std::forward的类型将被推断为左值引用或 const 左值引用。引用折叠规则会导致 T&&static_cast<T&&>(arg)在 std::forward 中始终解析为左值引用或 const 左值引用。

示例:

template<typename T>
T&& forward_with_deduction(T&& obj)
{
return static_cast<T&&>(obj);
}

void test(int&){}
void test(const int&){}
void test(int&&){}

template<typename T>
void perfect_forwarder(T&& obj)
{
test(forward_with_deduction(obj));
}

int main()
{
int x;
const int& y(x);
int&& z = std::move(x);

test(forward_with_deduction(7)); // 7 is an int&&, correctly calls test(int&&)
test(forward_with_deduction(z)); // z is treated as an int&, calls test(int&)

// All the below call test(int&) or test(const int&) because in perfect_forwarder 'obj' is treated as
// an int& or const int& (because it is named) so T in forward_with_deduction is deduced as int&
// or const int&. The T&& in static_cast<T&&>(obj) then collapses to int& or const int& - which is not what
// we want in the bottom two cases.
perfect_forwarder(x);
perfect_forwarder(y);
perfect_forwarder(std::move(x));
perfect_forwarder(std::move(y));
}

关于c++ - 为什么使用 std::forward 禁用模板参数推导?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24936441/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com