gpt4 book ai didi

c++ - std::move 模板参数是如何推导出来的?

转载 作者:可可西里 更新时间:2023-11-01 16:32:52 25 4
gpt4 key购买 nike

假设我们有:

foo(A&& a);

如果你这样做

A a;
foo(a);

它不会编译并且提示不能将左值绑定(bind)到 A&&。很好。

然而,鉴于 std::move 的签名,

template<class T> typename remove_reference<T>::type&& std::move(T&& a);

看起来它需要一个右值引用,就像在 foo 中一样,为什么下面的代码符合要求?

A a;
std::move(a);

a 不是左值吗?

此外,据说编译将实例化:

typename remove_reference<A&>::type&& std::move(A& && a);

我不明白为什么不是:

typename remove_reference<A>::type&& std::move(A && a);

在我看来 aA 类型,而不是 A&

最佳答案

不,move 不采用右值引用,它采用被社区称为通用引用 的内容。类型推导的模板参数根据引用折叠 的规则运行。这意味着:

  • 如果TK,那么T&&就是K&&
  • 如果TK&,那么T&&会折叠成K&
  • 如果TK&&,那么T&&会折叠成T&&

这就像 &&& 的逻辑与,其中 & 是 0 而 && 是1:

      &    &&
|-----------|
& | & | & |
|-----|-----|
&& | & | && |
|-----------|

这就是 move 对右值和左值起作用的方式。

例子:

template<typename T>
void f(T&&);

f<int> // T is int; plugging int into T makes int&& which is just int&&
f<int&> // T is int&; plugging int& into T is int& && which collapse to int&
f<int&&> // T is int&&; plugging int&& into T is int&& && which collapse to int&&

请注意,引用折叠仅发生在模板参数中;您不能直接键入 int&& && 并期望它能够编译。当然,您不会像那样手动指定类型。这些只是为了显示引用折叠到什么。

所以你真的会这样调用它:

int i;

f(i); // T is int&; int& && collapses to int&
f(4); // T is int&&; int&& && collapses to int&&

引用折叠也是 move 不返回 T&& 的原因:如果 T 是左值引用并且make move 只返回一个左值引用。您执行 remove_reference 以获得非引用类型,以便 && 真正意味着“右值引用”。

您可以在此处了解更多信息:http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers

关于c++ - std::move 模板参数是如何推导出来的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14531766/

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