了解'this'或其他参数是否为右值
get know whether 'this' or other arguments are rvalue
假设我们有class Base及其成员函数 BasedoSomething(const Base&other(。我想知道如何确定这个或其他对象是否是右值, 例如,我需要类似的东西
Base Base::doSomething(const Base& other) {
...
if(this_is_rvalue) {
// use resources of *this
}
else if(other_is_rvalue) {
// use resources of other
}
...
}
我知道可能的解决方案是使用模板化的朋友函数:
template<typename T1, typename T2, typename = typename std::enable_if<.....>::type>
friend Base doSomething(T1&& this_, T2&& other) {
...
if(std::is_rvalue_reference<T1&&>::value) {
// use resources of this_
return std::move(this_);
}
else if(std::is_rvalue_reference<T2&&>::value) {
// use resources of other
return std::move(other);
}
}
但是,在我的情况下,这种方法是非常不可取
的提前感谢!
您可以使用 4 个重载来执行此操作:
Base Base::doSomething(Base& other) && {
// *this is an rvalue and other is an lvalue
}
Base Base::doSomething(Base&& other) && {
// *this and other are rvalues
}
Base Base::doSomething(Base& other) & {
// *this and other are lvalues
}
Base Base::doSomething(Base&& other) & {
// *this is an lvalue and other is an rvalue
}
如果您希望能够接受const Base
,那么您可以制作这些模板并使用 SFINAE 来确保衰减的模板类型是这样的Base
template <typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, Base>, bool> = true>
Base Base::doSomething(T& other) && {
// *this is an rvalue and other is an lvalue
}
Base Base::doSomething(Base&& other) && {
// *this and other are rvalues
}
template <typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, Base>, bool> = true>
Base Base::doSomething(T& other) & {
// *this and other are lvalues
}
Base Base::doSomething(Base&& other) & {
// *this is an lvalue and other is an rvalue
}
另一种方法是仅使用两个重载和转发引用。 然后,您可以检查参数的类型是否为左值引用,以确定您是具有左值还是右值。 这在使用转发引用时有效,因为模板参数的类型被推断为T&
而不是T
如果它是右值。 那会给你这样的代码
template<typename A, typename B, typename C>
Base Base::doSomething(A&& other1, B&& other2, C&& other3) &
{
// this is always an lvalue in this function
if (std::is_lvalue_reference_v<A>)
// other1 is an lvalue
else
// other1 is a rvalue
if (std::is_lvalue_reference_v<B>)
// other2 is an lvalue
else
// other2 is a rvalue
if (std::is_lvalue_reference_v<C>)
// other3 is an lvalue
else
// other3 is a rvalue
}
template<typename A, typename B, typename C>
Base Base::doSomething(A&& other1, B&& other2, C&& other3) &&
{
// this is always an rvalue in this function
if (std::is_lvalue_reference_v<A>)
// other1 is an lvalue
else
// other1 is a rvalue
if (std::is_lvalue_reference_v<B>)
// other2 is an lvalue
else
// other2 is a rvalue
if (std::is_lvalue_reference_v<C>)
// other3 is an lvalue
else
// other3 is a rvalue
}
然后,如果需要,您可以通过添加来约束模板
std::enable_if_t<std::is_same_v<std::decay_t<A>, type_for_other1>,
std::is_same_v<std::decay_t<B>, type_for_other2>,
std::is_same_v<std::decay_t<B>, type_for_other3>, bool> = true
到模板参数,将模板限制为所需的参数类型。
到每一个
这是您区分左值this
和右值this
的方式:
Base Base::doSomething(const Base& other) const &
// ^^^^^^^ lvalue only
Base Base::doSomething(const Base& other) &&
// ^^ rvalue only
这是区分左值输入和右值输入的方式,通常:
Base Base::doSomething(const Base& other) {
// use resources of *this
}
Base Base::doSomething(Base&& other) {
// use resources of other
}
听起来你想要两者的某种结合,所以也许:
Base Base::doSomething(Base&&) const &;
Base Base::doSomething(const Base&) &&;
不过,这让我觉得有点奇怪。考虑一下你是否真的走在正确的道路上。
来自 https://en.cppreference.com/w/cpp/language/member_functions
非静态成员函数可以在没有 ref-qualifier、lvalue ref-qualifier(参数列表后的标记和(或 rvalue ref-qualifier(参数列表后的标记 &&(的情况下声明。在重载解析期间,X 类的非静态 cv 合格成员函数的处理方式如下:
- 无 ref 限定符:隐式对象参数具有对 cv 限定 X 的类型 lvalue 引用,并且还允许绑定 rvalue 隐含对象参数
- 左值引用限定符:隐式对象参数具有对 cv 限定 X 的右值引用类型
- 右值引用限定符:隐式对象参数具有对 cv 限定的 X 的右值类型引用
因此,如果您这样做:
Base Base::doSomething(const Base& other) &&;
此函数将被调用this
"重值">
相关文章:
- 在noexcept 规范中是否允许使用"this"?
- "this"指针的值在对象的生存期内是否恒定?
- 'this'指针是否可以在 c++ 标头声明中使用?
- "this"指向的对象是否与 const 对象相同?
- 了解'this'或其他参数是否为右值
- std::vector::assign/std::vector::operator=(const&) 是否保证在"this"中重用缓冲区?
- 是否是从等待返回到悬而未决的"this"实例的未定义行为?
- 在类方法中使用 "this" 指针是否是一种好的做法?
- 对于琐碎的对象,在"this"上调用新放置是否安全?
- 当取消引用运算符 (*) 重载时,*this 的使用是否受到影响?
- 是否可以获取'this'指针的地址?
- 在 C++ 中是否有等效于 Java 的'classname.this'?
- 对象的"this"指针是否等于指向其(单个)基类的指针?
- 是否可以在实例方法中使用带有"this"的重载运算符?
- 是否每个c++成员函数都隐式地将"this"作为输入
- 我的类方法中是否需要"this pointer"?
- 在类中使用时,lambda 捕获列表中的 [this] 和 [&] 是否等效?
- 是否有GCC选项来警告编写"this-field"而不是"this->field"?
- 安全地检查"this"是否为空
- 检查传递给方法的对象是否"this"