Return "this" 作为右值
Return "this" as rvalue
如预期的那样,以下代码未编译
#include <iostream>
class A
{
public:
A() = default;
~A() = default;
A(const A&) = delete;
A(A&&) = delete;
A& operator=(const A&) = delete;
A& operator=(A&&) = delete;
A& operator<<(const int i)
{
std::cout << "operator<< called" << std::endl;
return *this;
}
};
void foo(A&& a)
{
std::cout << "foo called" << std::endl;
}
int main()
{
A a; a << 14;
foo(std::move(a)); // works fine
foo(A() << 14); // does not compile
return 0;
}
将 class A 更改为
class A
{
public:
A() = default;
~A() = default;
A(const A&) = delete;
A(A&&) = delete;
A& operator=(const A&) = delete;
A& operator=(A&&) = delete;
A& operator<<(const int i) &
{
std::cout << "operator<< called on lvalue" << std::endl;
return *this;
}
A&& operator<<(const int i) &&
{
std::cout << "operator<< called on rvalue" << std::endl;
return std::move(*this);
}
};
编译程序。然而,return 右值与 std::move 通常不是一个好主意,因为它会 return 悬空引用或阻止编译器进行某些优化。
所描述的案例是经验法则中的少数例外之一"do not return by rvalue"还是应该以不同的方式解决问题?
非常感谢!
此代码完全有效且安全。由于您的对象已经是
中的右值
A&& operator<<(const int i) &&
再次将其转换为右值(移动)不会改变代码的安全性。在这种情况下不会进行 NRVO 优化,因此代码速度不太可能受到影响。
所以当你制定它时,我会说 "yes, this is an exception to the rule"
此外,这条规则并不通用:如果您了解正在发生的事情(这就是您问这个问题的原因),您可以依靠自己的判断力而不是依靠它。
如预期的那样,以下代码未编译
#include <iostream>
class A
{
public:
A() = default;
~A() = default;
A(const A&) = delete;
A(A&&) = delete;
A& operator=(const A&) = delete;
A& operator=(A&&) = delete;
A& operator<<(const int i)
{
std::cout << "operator<< called" << std::endl;
return *this;
}
};
void foo(A&& a)
{
std::cout << "foo called" << std::endl;
}
int main()
{
A a; a << 14;
foo(std::move(a)); // works fine
foo(A() << 14); // does not compile
return 0;
}
将 class A 更改为
class A
{
public:
A() = default;
~A() = default;
A(const A&) = delete;
A(A&&) = delete;
A& operator=(const A&) = delete;
A& operator=(A&&) = delete;
A& operator<<(const int i) &
{
std::cout << "operator<< called on lvalue" << std::endl;
return *this;
}
A&& operator<<(const int i) &&
{
std::cout << "operator<< called on rvalue" << std::endl;
return std::move(*this);
}
};
编译程序。然而,return 右值与 std::move 通常不是一个好主意,因为它会 return 悬空引用或阻止编译器进行某些优化。
所描述的案例是经验法则中的少数例外之一"do not return by rvalue"还是应该以不同的方式解决问题?
非常感谢!
此代码完全有效且安全。由于您的对象已经是
中的右值A&& operator<<(const int i) &&
再次将其转换为右值(移动)不会改变代码的安全性。在这种情况下不会进行 NRVO 优化,因此代码速度不太可能受到影响。
所以当你制定它时,我会说 "yes, this is an exception to the rule"
此外,这条规则并不通用:如果您了解正在发生的事情(这就是您问这个问题的原因),您可以依靠自己的判断力而不是依靠它。