gpt4 book ai didi

c++ - 右值模板参数隐式用作左值,并且 std::forwarding 工作

转载 作者:行者123 更新时间:2023-11-30 02:04:37 25 4
gpt4 key购买 nike

This example std::forward 的用法让我很困惑。这是我编辑的版本:

#include <iostream>
#include <memory>
#include <utility>
using namespace std;

struct A{
A(int&& n) { cout << "rvalue overload, n=" << n << "\n"; }
A(int& n) { cout << "lvalue overload, n=" << n << "\n"; }
};

template<typename> void template_type_dumper();

template<class T, class U>
unique_ptr<T> make_unique(U&& u){
//Have a "fingerprint" of what function is being called
static int dummyvar;
cout<<"address of make_unique::dummyvar: "<<&dummyvar<<endl;
//g++ dumps two warnings here, which reveal what exact type is passed as template parameter
template_type_dumper<decltype(u)>;
template_type_dumper<U>;

return unique_ptr<T>(new T(forward<U>(u)));
}

int main()
{
unique_ptr<A> p1 = make_unique<A>(2); // rvalue
int i = 1;
unique_ptr<A> p2 = make_unique<A>(i); // lvalue
}

输出是

address of make_unique::dummyvar: 0x6021a4
rvalue overload, n=2
address of make_unique::dummyvar: 0x6021a8
lvalue overload, n=1

关于引用 template_type_dumper 的警告表明,在第一个实例化中,decltype(u) = int&&U = int,对于第二个 decltype(u) = int&U = int&

很明显,正如预期的那样,有两个不同的实例化,但她是我的问题:

  1. std::forward 如何在这里工作?在第一个实例化中,它的模板参数是明确的 U = int,它怎么知道它必须返回一个右值引用?如果我改为指定 U&& 会怎样?
  2. make_unique 声明采用右值引用。为什么 u 可以是左值引用?是否有任何我遗漏的特殊规则?

最佳答案

make_unique is declared to take a rvalue-reference. How come u can be a lvalue-reference? Is there any special rule that I am missing?

make_unique被声明为引用。要推断出什么样的引用。如果 foo 类型的左值通过,U推导为 foo&U&&变成 foo&由于引用折叠规则(基本上,“组合”一个左值引用与另一个引用总是产生一个左值引用;组合两个右值引用产生一个右值引用)。如果类型为 foo 的右值通过,U推导为 fooU&&foo&& .

这是支持完美转发的因素之一:使用 U&&你可以同时使用左值和右值,以及 U被推断为匹配适当的值类别。然后用 std::forward您可以转发保留相同值类别的值:在第一种情况下,您会得到 std::forward<foo&>它转发一个左值,在第二个中,你得到 std::forward<foo>它转发一个右值。

In the first instantiation, its template argument is explicitly U = int, how can it know that it has to return a rvalue-reference?

因为std::forward<T>的返回类型总是 T&& .如果你通过 int它返回 int&& .如果你通过 int&它返回 int&再次因为引用折叠规则。

What would happen if I specified U&& instead?

你会得到 std::forward<int&&>和引用折叠规则使int&& &&右值引用仍然是:int&& .

关于c++ - 右值模板参数隐式用作左值,并且 std::forwarding 工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10389958/

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