2

在 C++ 中,不可能将 r 值参数绑定到非constl 值引用。但我注意到,当我调用 r-value 对象时,返回*this它的方法会以某种方式编译。

示例:不经意间,这段代码将无法编译

    class X
    {
    };
    
    void bar(X&)
    {
    }

    int main()
    {
      foo(X{}); //  invalid initialization of non-const reference of type 'X&' from an rvalue of type 'X'
    }

但是添加一个简单的方法X使其可编译:

class X
{
   public:
   X& foo() { return *this; }  
};

void bar(X&)
{
}

int main()
{
  bar(X{}.foo());
}

为什么它有效?是不是说调用后右foo值对象就变成左值对象了?使用这种结构是否安全?有没有其他方法可以在不创建新方法(类似X.this)的情况下达到类似的效果?

4

1 回答 1

2

正如评论中提到的,foo返回一个左值,而不是一个右值,所以将它传递给bar就好了。

X{}.foo()如果即使它X{}本身是一个右值也返回一个左值感觉很奇怪,可以把它想象foo()成一个函数,它(隐式地)通过左值引用获取this并返回一些东西(恰好是this指向的东西)。现在,怎么foothis?它接受右值吗?它接受左值吗?两者都可以,但是您可以编写一些东西以便只允许一种用法(在此处查找ref 限定的成员函数 ):

class X
{
   public:
   X& fool() &  { return *this; } // called on lvalue objects
   X& foor() && { return *this; } // called on rvalue objects
};

void bar(X&)
{
}

int main()
{
    X x;
  bar(x.fool());
  //bar(x.foor());   // fails
  //bar(X{}.fool()); // fails
  bar(X{}.foor());
}

但是,请注意您的操作:

#include <iostream>
#include <type_traits>
class X
{
   public:
   X& fool() &  { return *this; }
   X& foor() && { return *this; }
   ~X() { std::cout << "dtor\n"; }
};

void bar(X&)
{
}

int main()
{
  auto& xxx = X{}.foor();
  // use xxx, but X{} has been destroyed
  std::cout << "bye\n";
}
于 2021-01-19T08:27:58.090 回答