使用 *this 从右值进行的预期无效初始化
Intended invalid intialization from rvalue using *this
在 C++ 中,不可能将右值参数绑定到非 const
左值引用。但我注意到,当我调用 r 值对象时,返回 *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
)?
如评论中所述,foo
returns 是左值,而不是右值,因此将其传递给 bar
就可以了。
如果 X{}.foo()
returns 一个左值感觉很奇怪,即使 X{}
本身是一个右值,请将 foo()
视为一个函数(隐含地)接受 this
和 returns 某物(恰好是 this
指向的东西)通过左值引用。现在,foo
怎么取 this
?它接受右值吗?它接受左值吗?两者都是,但你可以编写只允许一种用法的东西(寻找 ref-qualified 成员函数 here):
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";
}
在 C++ 中,不可能将右值参数绑定到非 const
左值引用。但我注意到,当我调用 r 值对象时,返回 *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
)?
如评论中所述,foo
returns 是左值,而不是右值,因此将其传递给 bar
就可以了。
如果 X{}.foo()
returns 一个左值感觉很奇怪,即使 X{}
本身是一个右值,请将 foo()
视为一个函数(隐含地)接受 this
和 returns 某物(恰好是 this
指向的东西)通过左值引用。现在,foo
怎么取 this
?它接受右值吗?它接受左值吗?两者都是,但你可以编写只允许一种用法的东西(寻找 ref-qualified 成员函数 here):
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";
}