与往常使用std::move
'd的变量一样,之后使用它们是不安全的。
由于我编写了一个代码,我鼓励用户在不同的场合应用std::move
,我想避免以错误的方式使用它,至少在几个关键的地方(所以有选择地说) “防止马基雅维利”。
因此,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{};
}
答案 0 :(得分:7)
根据[namespace.std]:
,您的代码显示未定义的行为如果将声明或定义添加到命名空间
std
或将其添加到 命名空间std
中的命名空间,除非另有说明。程序可以添加模板专业化 仅当声明取决于用户定义的类型时,才能将任何标准库模板添加到命名空间std
并且专业化符合原始模板的标准库要求,并未明确说明 禁止的。
您的用例不属于&#34;否则指定&#34;雨伞。除了未定义之外,还有一些值得怀疑的问题......你不允许这样做:
A a;
f(std::move(a));
// just don't use a here
尽管可能比f(a)
提高了性能。但是用户仍然可以明确地编写演员来完成相同的结果:
f(static_cast<A&&>(a)); // slightly more verbose move
答案 1 :(得分:3)
与使用std :: move'd的变量一样,它是不安全的 之后使用它们
这根本不是真的。使用已经移动的东西是完全安全的。在被标准移动后,有很多地方需要使用,例如std::swap
,甚至只是破坏当地人。
无法做的事情是假设他们有任何特定的有效状态。但是他们必须具有某些有效状态。如果您正在创作A
并且它不遵守这些规则,那么A
就会被破坏并且应该被修复,而不是针对该问题进行帮助。
答案 2 :(得分:0)
A a;
auto a_moved = std :: move(a); //禁止移动左值参考号 a.do_something(); //否则这可能会有问题
std :: move()的要点是取一个左值并返回一个右值,这样就可以调用你的移动构造函数或移动赋值。因此,要么删除移动构造函数并移动分配,要么用户只需要知道他们在做什么。以下是有关std :: move()http://en.cppreference.com/w/cpp/utility/move
的一些信息