gpt4 book ai didi

c++ - 为什么 std::forward 返回 static_cast 而不是 static_cast

转载 作者:IT老高 更新时间:2023-10-28 22:26:19 27 4
gpt4 key购买 nike

让我们有一个名为 Y 的重载函数:

void Y(int& lvalue)
{ cout << "lvalue!" << endl; }

void Y(int&& rvalue)
{ cout << "rvalue!" << endl; }

现在,让我们定义一个类似于 std::forward 的模板函数

template<class T>
void f(T&& x)
{
Y( static_cast<T&&>(x) ); // Using static_cast<T&&>(x) like in std::forward
}

现在看看 main()

int main()
{
int i = 10;

f(i); // lvalue >> T = int&
f(10); // rvalue >> T = int&&
}

正如预期的那样,输出是

lvalue!
rvalue!

现在回到模板函数 f()并替换 static_cast<T&&>(x)static_cast<T>(x) .让我们看看输出:

lvalue!
rvalue!

都是一样的!为什么?如果它们相同,那为什么 std::forward<>x 返回一个类型转换至T&& ?

最佳答案

左值与右值分类保持不变,但效果完全不同(并且值类别确实发生了变化 - 尽管在您的示例中不是以可观察的方式)。让我们回顾一下这四种情况:

template<class T>
void f(T&& x)
{
Y(static_cast<T&&>(x));
}

template<class T>
void g(T&& x)
{
Y(static_cast<T>(x));
}

如果我们调用 f带有左值,T将推断为一些 X& ,所以类型转换引用折叠 X& && ==> X& ,所以我们最终得到相同的左值并且没有任何变化。

如果我们调用 f带有右值,T将推断为一些 X所以 Actor 只是转换xx 的右值引用, 所以它变成了一个右值(特别是一个 xvalue)。

如果我们调用 g使用左值,所有相同的事情都会发生。没有必要折叠引用,因为我们只是使用 T == X& ,但类型转换仍然是空操作,我们仍然得到相同的左值。

但是如果我们调用 g使用右值,我们有 static_cast<T>(x)这将复制 x .该拷贝 一个右值(正如您的测试所验证的那样 - 除了现在它是一个纯右值而不是一个 xvalue),但它充其量是一个额外的、不必要的拷贝,并且会导致编译失败(如果 T 是可移动但不可复制)在最坏的情况下。与 static_cast<T&&>(x) ,我们正在转换到一个引用,它不会调用拷贝。

这就是我们这样做的原因T&& .

关于c++ - 为什么 std::forward 返回 static_cast<T&&> 而不是 static_cast<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38251660/

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