当一个可移动对象插入std :: set失败时会发生什么?

Jam*_*nze 12 c++ c++11

如果我调用可移动对象会发生 std::set<>::insert什么,并且插入不会发生,因为已经有一个对象存在于该集合中.特别是,以下是有效的:

struct Object
{
    std::string key;
    //  ...

    struct OrderByKey
    {
        bool operator()( Object const& lhs, Object const& rhs) const
        {
            return lhs.key < rhs.key;
        }
    };

    Object( Object&& other )
        : key(std::move(other.key))
    // ...
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

和:

std::set<Object, Object::OrderByKey> registry;
void
register(Object&& o)
{
    auto status = registry.insert(std::move(o));
    if (!status.second)
        throw std::runtime_error("Duplicate entry for " + o.key);
}
Run Code Online (Sandbox Code Playgroud)

之后registry.insert,当没有插入时, o已移动或未移动.(如果它可能已被移动,我需要事先保存字符串的副本,以便在错误消息中使用它.(是的,我知道我总是可以写:

throw std::runtime_error( "Duplicate entry for " + status->first.key );
Run Code Online (Sandbox Code Playgroud)

这是我可能会做的.但我仍然想知道标准对此有何看法.)

Die*_*ühl 6

一个std::move()传递给标准库函数版的对象应该被认为是从移动:图书馆是免费的考虑对象是其唯一的参考,也就是说,它可以将其移动,即使它不使用它.相关条款是17.6.4.9 [res.on.arguments]第2段,第3个子弹(在C++ 11和C++ 14中似乎相同):

如果函数参数绑定到右值引用,则实现可以假定此参数是对此参数的唯一引用....