Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要引用折叠规则T&;的示例&&&-&燃气轮机;T&&;关于VS2017 给出C++引用折叠规则的几个来源如下: A& & becomes A& A& && becomes A& A&& & becomes A& A&& && becomes A&&_C++_Templates_Forwarding Reference - Fatal编程技术网

需要引用折叠规则T&;的示例&&&-&燃气轮机;T&&;关于VS2017 给出C++引用折叠规则的几个来源如下: A& & becomes A& A& && becomes A& A&& & becomes A& A&& && becomes A&&

需要引用折叠规则T&;的示例&&&-&燃气轮机;T&&;关于VS2017 给出C++引用折叠规则的几个来源如下: A& & becomes A& A& && becomes A& A&& & becomes A& A&& && becomes A&&,c++,templates,forwarding-reference,C++,Templates,Forwarding Reference,(例如) 我可以给一个&&&成为一个& template <class T> void f1(T&& param) { // T t = 5; // does not compile because T is T& param++; // param collapses from int&&&& to int&& } void demo() { int x = 8; int &

(例如)

我可以给一个&&&成为一个&

template <class T> void f1(T&& param) {
    // T t = 5;  // does not compile because T is T&
    param++; // param collapses from int&&&& to int&&
}

void demo()
{
    int x = 8;
    int &y = x;
    f1(y);   // OK T will still be int&, param will go to int&&& -> collapses to int&
    cout << y;  // prints 9
}
模板无效f1(T&¶m){
//T=5;//不编译,因为T是T&
param++;//param从int&&&&折叠为int&&
}
void demo()
{
int x=8;
int&y=x;
f1(y);//OK T仍然是int&,param将转到int&&&->折叠为int&
库特
有人能帮我演示一个类似的例子吗?在这个例子中,T被推导为T&&并且参数从T&&&&折叠为T&&&&

如果我们讨论的是实际的推断,其中模板参数
T
没有明确给出或以某种方式默认,那是不可能的。原因是转发不仅依赖于引用折叠

首先,我们必须注意C++中的一个函数(模板)的参数总是某种表达式。表达式从来没有引用类型。

[expr.type]

如果表达式最初的类型为“对T的引用” ([dcl.ref],[dcl.init.ref]),类型在任何 进一步分析。表达式指定对象或函数 由引用表示,表达式是左值或 xvalue,具体取决于表达式

实际上,您不能为引用类型的函数生成参数。因此,在正常情况下,
t
不能推断为引用。转发也依赖于模板中引用函数参数的特殊情况

[临时扣减呼叫]

如果p是引用类型,则p引用的类型用于 类型推断。[…]转发引用是对的右值引用 不代表模板的cv非限定模板参数 类模板的参数(在类模板参数期间) 扣减([over.match.class.decreate])。如果P是转发引用 参数是一个左值,类型“levaluereferencetoa”是 用于代替用于类型推断的

如您所见,转发引用是专门围绕作为参数提供的表达式的值类别设计的。只有当表达式是左值时,参数的类型才被视为“对参数的左值引用”。否则,不会进行调整。因此,
T
将被推断为所引用的类型


引用折叠规则仅在显式给出类型参数时起作用。在这种情况下,当以某种方式提供
int&
时,我们通过引用折叠获得右值引用。但这不是在模板参数推导之后。

在注释者和其他答案海报的帮助下,我想出了是演示:

template <class T> void f1() {
    int x = 5; // an lvalue
    //T t1 = x; // compiles when T is int or int&, fails when T is int&
    //T& t2 = x; // always compiles, becomes int&. Can check with ++t2; cout << x;
    //T&& t3 = x; // compiles when T is int&, fails when t3 is &&
}

void demo()
{
    //f1<int>();     // T becomes int, t1=int,  t2=int&   t3=int&&
    //f1<int&>(); // T becomes int&  t1=int& t2=int& t3=int&
    f1<int&&>(); // T becomes int&&, t1=int&&  t2=int&, t3=int&&
}
template void f1(){
int x=5;//左值
//T t1=x;//当T为int或int&时编译,当T为int时失败&

//t/t2= x;//总是编译,可以用++t2检查;cOUT,你可以称它为<代码> f1(8);< /COD>。我尝试并给出了编译器错误,正如你所期望的,即<代码> T T2= T;< /C> >不会编译。例如,考虑<代码> F1(…))
。这里,
T
将是
some_type&&
,而
param
的类型将从
some_type&&&&&
折叠为
some_type&&&
。感谢您的详细回复。这里有很多内容。首先,我喜欢通过使用typ显式实例化模板来展示示例的想法e、 我肯定会使用它。至于不能为引用类型的函数生成参数,在某些情况下,我认为您可以。例如,当我的第一个示例中的参数为int&并且参数为T&&时,T变为int&正如我的第一个示例所示。如果我错了,请纠正我。@GonenI-argument从来都不是
int&
。当您传递
y
时,它是
int
类型的id表达式(如第一段所述)。它也是一个左值,这就是转发引用的模板参数推断将类型调整为
int&
。但它与
y
本身(作为表达式)不同属于
int&
类型。这是这里的关键。当参数不是左值时,没有调整。因此我们只剩下值类型。
template <class T> void f1() {
    int x = 5; // an lvalue
    //T t1 = x; // compiles when T is int or int&, fails when T is int&
    //T& t2 = x; // always compiles, becomes int&. Can check with ++t2; cout << x;
    //T&& t3 = x; // compiles when T is int&, fails when t3 is &&
}

void demo()
{
    //f1<int>();     // T becomes int, t1=int,  t2=int&   t3=int&&
    //f1<int&>(); // T becomes int&  t1=int& t2=int& t3=int&
    f1<int&&>(); // T becomes int&&, t1=int&&  t2=int&, t3=int&&
}