相关疑难解决方法(0)

移动物体怎么办?

标准是否准确定义了对象移动后我可以对其做什么?我曾经认为你用移动物体做的所有事情都可以破坏它,但这还不够.

例如,采用swap标准库中定义的函数模板:

template <typename T>
void swap(T& a, T& b)
{
    T c = std::move(a); // line 1
    a = std::move(b);   // line 2: assignment to moved-from object!
    b = std::move(c);   // line 3: assignment to moved-from object!
}
Run Code Online (Sandbox Code Playgroud)

显然,必须可以分配给移动的对象,否则第2行和第3行将失败.那么移动对象我还能做些什么呢?我在哪里可以找到标准中的这些细节?

(顺便说一句,为什么它T c = std::move(a);不是T c(std::move(a));第1行呢?)

c++ swap variable-assignment move-semantics c++11

136
推荐指数
2
解决办法
1万
查看次数

119
推荐指数
1
解决办法
6万
查看次数

重用移动的容器?

重用移动容器的正确方法是什么?

std::vector<int> container;
container.push_back(1);
auto container2 = std::move(container);

// ver1: Do nothing
//container2.clear(); // ver2: "Reset"
container = std::vector<int>() // ver3: Reinitialize

container.push_back(2);
assert(container.size() == 1 && container.front() == 2);
Run Code Online (Sandbox Code Playgroud)

从我在C++ 0x标准草案中读到的内容; ver3似乎是正确的方法,因为移动后的对象在a中

"除非另有规定,否则此类移动物体应处于有效但未指明的状态."

我从来没有找到任何"以其他方式指定"的实例.

虽然我发现ver3有点回旋并且会有更多首选ver1,虽然vec3可以允许一些额外的优化,但另一方面很容易导致错误.

我的假设是否正确?

c++ move-semantics c++11

78
推荐指数
2
解决办法
8036
查看次数

有没有必要在c ++ 11中定义只移动对象?

我之前有一个关于使用unique-ptrs的问题.我得到这个答案,建议使用仅移动对象.我定义了一个类如下:

class B {
    const string objName;
public:

    B ( B && ) = default;
    B &  operator= ( B && ) = default;
    B ( const B & ) = delete;
    B & operator= ( const B & ) = delete;

    B(const string & name) :
            objName(name) {

    }

    virtual ~B();

    const string name() const { return objName;};
}
Run Code Online (Sandbox Code Playgroud)

我用这句话打电话给B:

class A {
A(){}
void take(B b);
}

A a; 
B b("test");
cout<<b.name();
a.take(std::move(b));
cout<<b.name();
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 即使我已经默认了移动构造函数,我也不能写a.take(b)并且我正在编译错误.我理解复制constrctor已被删除但似乎逻辑选择是在默认情况下使用move构造函数而不需要像这样编写std …

c++ smart-pointers std pass-by-value c++11

8
推荐指数
1
解决办法
4205
查看次数

std :: unique_ptr :: release()vs std :: move()

我有一个表示运行时上下文并构建树的类,树根保存在unique_ptr.在构建树时,我想要提取树.这是它的外观(不可运行,这不是一个调试问题):

class Context {
    private:
    std::unique_ptr<Node> root{new Node{}};
    public:
    // imagine a constructor, attributes and methods to build a tree
    std::unique_ptr<Node> extractTree() {
        return std::move(this->root);
    }
};
Run Code Online (Sandbox Code Playgroud)

所以我曾经std::move()Context实例中提取根节点.

然而,有使用的替代方案,std::move()例如:

std::unique_ptr<Node> extractTree() {
    // This seems less intuitive to me
    return std::unique_ptr<Node>{this->root.release()};
}
Run Code Online (Sandbox Code Playgroud)

std::move()最好的选择吗?

c++ c++11

6
推荐指数
1
解决办法
4563
查看次数

在线程之间移动向量

我有一个线程,通过这样的公共接口不断收集数据项:

class MyThread {
public:
    class Item {
        // ...
    };

    startup();
    shutdown();

    bool hasItems() const;

    // retrieve collected items
    std::vector<Item>&& items();
private:
    std::mutex itemMutex;
    std::vector<Item> currentItems;
};
Run Code Online (Sandbox Code Playgroud)

检索项目还应清除线程的项目列表.我返回一个右值,以便在调用端调用移动构造函数.当然,检索项应该是线程安全的,因此实现如下所示:

std::vector<MyThread::Item>&& MyThread::items() {
    std::lock_guard<std::mutex> lock(itemMutex);
    return std::move(currentItems);
}
Run Code Online (Sandbox Code Playgroud)

我认为锁定在这里发布得太早:函数返回rvalue'd向量,但是当std::lock_guard销毁并释放互斥锁时,移动构造函数不一定会被调用.所以从我的理解来看,这不是线程安全的.我对吗?如何使其线程安全?

c++ multithreading move-semantics c++11

5
推荐指数
1
解决办法
1127
查看次数

在 std::unordered_map 中移动插入/放置失败后恢复移动的元素

std::unordered_map使用insertoremplace方法和移动语义填充了一个。当发生关键冲突时,元素不会插入到地图中,但移动的元素无论如何都会被删除:

#include <unordered_map>
#include <iostream>

int main(){
    std::unordered_map<int, std::string> m;
    m.insert(std::make_pair<int, std::string>(0, "test"));
    std::string s = "test";
    
    // try insert
    auto val = std::make_pair<int, std::string>(0, std::move(s));
    if(m.insert(std::move(val)).second){
        std::cout << "insert successful, ";
    }else{
        std::cout << "insert failed, ";
    }
    std::cout << "s: " << s << ", val.second: " << val.second <<  std::endl;
    
    // try emplace
    s = "test";
    if(m.emplace(0, std::move(s)).second){
        std::cout << "emplace successful, ";
    }else{
        std::cout << "emplace failed, ";
    }
    std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ unordered-map move-semantics

5
推荐指数
1
解决办法
637
查看次数