【问题标题】:passing rvalue raises cannot bind to lvalue传递右值引发不能绑定到左值
【发布时间】:2016-07-27 05:00:44
【问题描述】:

程序如下:

#include <iostream>
using namespace std;

template <typename F, typename T1, typename T2>
void flip2(F f, T1 &&t1, T2 &&t2)
{
      f(t2, t1);
}

void g(int &&i, int &j)
{
      cout << i << " " << j << endl;
}

int main(void)
{
      int i = 1;
      flip2(g, i, 42);
}

编译器抱怨:

error: rvalue reference to type 'int' cannot bind to lvalue of type 'int'

但据我了解,由于T2是用int实例化的,那么t2的类型就是int&amp;&amp;,所以应该允许它传递给函数g的第一个参数(@987654328 @)。

我的理解有什么问题?

【问题讨论】:

    标签: c++ templates c++11 perfect-forwarding


    【解决方案1】:
    f(t2, t1);
    

    t2 有一个名字,所以它是一个左值。它的 type 是右值,但在表达式中它的类型是左值。为了将其作为右值引用传递,您需要使用std::forwardmove 或在此处强制转换不合适,因为 T1 和 T2 实际上是通用引用不是右值引用,见编辑)。

    #include <iostream>
    using namespace std;
    
    template <typename F, typename T1, typename T2>
    void flip2(F f, T1 &&t1, T2 &&t2)
    {
          f(std::forward<T2>(t2), std::forward<T1>(t1));
    }
    
    void g(int &&i, int &j)
    {
          cout << i << " " << j << endl;
    }
    
    int main(void)
    {
          int i = 1;
            flip2(g, i, 42);
    }
    

    http://ideone.com/Aop2aJ

    --- 为什么---

    考虑:

    template<typename T>
    void printAndLog(T&& text) {
        print(text);
        log(text);
    }
    
    int main() {
        printAndLog(std::string("hello, world!\n"));
    }
    

    当你使用一个变量的名字时,表达式类型是左值(glvalue?);右值被丢弃。否则,在上面的示例中,我们将把text 输给print()。相反,当我们希望我们的右值表现得像一个时,我们必须明确:

    template<typename T>
    void printAndLog(T&& text) {
        print(text);
        log(std::forward<T>(text));  // if text is an rvalue, give it up.
    }
    

    --- 编辑---

    我使用了std::forward,因为T1&amp;&amp;T2&amp;&amp; 是通用引用,而不是右值引用。 https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers

    【讨论】:

    • 不明白为什么t2是左值,t2的类型是int &amp;&amp;,好像是右值引用。
    • @Charles0429 t2 有一个名字,你可以取它的地址,所以,它是一个左值。它可以绑定到右值的事实并不意味着它是一个右值
    猜你喜欢
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 2014-10-31
    • 2017-04-13
    • 2016-06-09
    • 2011-02-14
    相关资源
    最近更新 更多