C++ 不允许转换为右值引用
C++ disallow cast to rvalue reference
与已经 std::move
的变量一样,之后使用它们是不安全的。
由于我编写了鼓励用户在各种场合应用 std::move
的代码,因此我想避免以错误的方式使用它,至少在一些关键的地方(以便选择性地说 "protect against Machiavelli").
因此,std::move
的以下重载是否是一个有效的方法?还是您不鼓励使用它?
struct A
{
void do_something() const { /* ... whatever ... */ }
};
namespace std
{
auto move(A& t) noexcept = delete;
auto move(A const& t) noexcept = delete;
//possibly the same for volatile qualifier
//possibly also specialize static_cast<A const&>, static_cast<A&>, etc.
}
// possibly set up another function "my_private_move"
// which I can use exclusively where it is appropriate.
int main()
{
A a;
// auto a_moved = std::move(a); //disallow move of lvalue ref
a.do_something(); //otherwise this could be problematic
A(A{}); //direct initialization via move constructor is ok
auto x2 = A{};
}
根据 [namespace.std]:
,您的代码表现出未定义的行为
The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std
or to a
namespace within namespace std
unless otherwise specified. A program may add a template specialization
for any standard library template to namespace std
only if the declaration depends on a user-defined type
and the specialization meets the standard library requirements for the original template and is not explicitly
prohibited.
您的用例不属于 "otherwise specified" 范畴。除了未定义之外,它的价值值得怀疑......你不允许这样做:
A a;
f(std::move(a));
// just don't use a here
尽管这可能比 f(a)
有性能改进。但是用户仍然可以显式地编写转换来实现相同的结果:
f(static_cast<A&&>(a)); // slightly more verbose move
As always with variables which have been std::move'd, it is unsafe to
use them afterwards
这根本不是真的。使用已经搬走的东西是绝对安全的。在被标准移动后,有很多地方必须使用它们,例如std::swap
甚至只是破坏局部变量。
你不能做的是假设他们有任何特定有效状态。但他们必须有一些有效状态。如果您正在创作 A
并且它不遵守这些规则,那么 A
已经损坏并且应该被修复,而不是用创可贴来解决这个问题。
A a;
auto a_moved = std::move(a); //disallow move of lvalue ref
a.do_something(); //otherwise this could be problematic
std::move() 的要点是取左值,return 取右值,以便可以调用移动构造函数或移动赋值。因此,要么删除移动构造函数和移动赋值,要么您的用户只需要知道他们在做什么。这是关于 std::move() http://en.cppreference.com/w/cpp/utility/move
的一些信息
与已经 std::move
的变量一样,之后使用它们是不安全的。
由于我编写了鼓励用户在各种场合应用 std::move
的代码,因此我想避免以错误的方式使用它,至少在一些关键的地方(以便选择性地说 "protect against Machiavelli").
因此,std::move
的以下重载是否是一个有效的方法?还是您不鼓励使用它?
struct A
{
void do_something() const { /* ... whatever ... */ }
};
namespace std
{
auto move(A& t) noexcept = delete;
auto move(A const& t) noexcept = delete;
//possibly the same for volatile qualifier
//possibly also specialize static_cast<A const&>, static_cast<A&>, etc.
}
// possibly set up another function "my_private_move"
// which I can use exclusively where it is appropriate.
int main()
{
A a;
// auto a_moved = std::move(a); //disallow move of lvalue ref
a.do_something(); //otherwise this could be problematic
A(A{}); //direct initialization via move constructor is ok
auto x2 = A{};
}
根据 [namespace.std]:
,您的代码表现出未定义的行为The behavior of a C++ program is undefined if it adds declarations or definitions to namespace
std
or to a namespace within namespacestd
unless otherwise specified. A program may add a template specialization for any standard library template to namespacestd
only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
您的用例不属于 "otherwise specified" 范畴。除了未定义之外,它的价值值得怀疑......你不允许这样做:
A a;
f(std::move(a));
// just don't use a here
尽管这可能比 f(a)
有性能改进。但是用户仍然可以显式地编写转换来实现相同的结果:
f(static_cast<A&&>(a)); // slightly more verbose move
As always with variables which have been std::move'd, it is unsafe to use them afterwards
这根本不是真的。使用已经搬走的东西是绝对安全的。在被标准移动后,有很多地方必须使用它们,例如std::swap
甚至只是破坏局部变量。
你不能做的是假设他们有任何特定有效状态。但他们必须有一些有效状态。如果您正在创作 A
并且它不遵守这些规则,那么 A
已经损坏并且应该被修复,而不是用创可贴来解决这个问题。
A a;
auto a_moved = std::move(a); //disallow move of lvalue ref
a.do_something(); //otherwise this could be problematic
std::move() 的要点是取左值,return 取右值,以便可以调用移动构造函数或移动赋值。因此,要么删除移动构造函数和移动赋值,要么您的用户只需要知道他们在做什么。这是关于 std::move() http://en.cppreference.com/w/cpp/utility/move
的一些信息