gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 12:59:54 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/7779900/

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