首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rvalue模板参数隐式用作lvalue,并且std::forwarding工作

rvalue模板参数隐式用作lvalue,并且std::forwarding工作
EN

Stack Overflow用户
提问于 2012-04-30 20:12:55
回答 1查看 434关注 0票数 1

这个例子关于std::forward的用法令我费解。这是我编辑的版本:

代码语言:javascript
复制
#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
}

输出是

代码语言:javascript
复制
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,它如何知道它必须返回一个rvalue引用?如果我指定了U&&,会发生什么?
  2. make_unique被声明为接受rvalue-引用。为什么u可以成为一个独立引用呢?我错过了什么特别的规则吗?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-30 20:26:20

make_unique被声明为接受rvalue-引用。为什么你能成为一个独立的参考?我错过了什么特别的规则吗?

make_unique被声明为引用。要推断出这种引用是什么类型的。如果传递类型为foo的lvalue,则由于引用折叠规则(基本上,将一个lvalue引用与另一个引用“组合”总是产生一个lvalue引用;将两个rvalue引用组合为一个rvalue引用),U被推断为foo&U&&成为foo&。如果传递foo类型的r值,则U被推导为fooU&&foo&&

这是支持完美转发的因素之一:使用U&&,您可以同时获取lvalue和rvalue,并推导出U以匹配适当的值类别。然后,使用std::forward,您可以转发保持相同值类别的值:在第一种情况下,得到转发lvalue的std::forward<foo&>,在第二种情况下,得到转发rvalue的std::forward<foo>

在第一个实例化中,它的模板参数显式为U= int,它如何知道它必须返回rvalue-引用?

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

如果我指定了U&&相反,会发生什么?

您可以让std::forward<int&&>和引用折叠规则使int&& &&仍然是一个rvalue引用:int&&

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10389958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档