C++禁止转换为右值引用

dav*_*igh 0 c++ move c++11

和往常一样的变量一样,std::move之后使用它们是不安全的.

由于我编写了一个代码,我鼓励用户std::move在不同的场合应用,我想避免以错误的方式使用它,至少在几个关键的地方(所以有选择地说"防止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{};                      
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 7

根据[namespace.std],您的代码显示未定义的行为:

如果C++程序将声明或定义添加到命名空间std或命名空间中的命名空间std,则除非另有说明,否则C++程序的行为是未定义的.std只有当声明取决于用户定义的类型并且特化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间.

您的用例不属于"另有规定"的保护伞.除了未定义,这是值得怀疑的......你不允许这样做:

A a; 
f(std::move(a)); 
// just don't use a here
Run Code Online (Sandbox Code Playgroud)

尽管这可能会提高性能f(a).但是用户仍然可以显式地编写强制转换来完成相同的结果:

f(static_cast<A&&>(a)); // slightly more verbose move
Run Code Online (Sandbox Code Playgroud)