我很难理解Stroustrup先生在他的新书TCPL第4版的第3.3.3节中的片段

I'm having some difficulty understanding Mr. Stroustrup snippet in section 3.3.3 of his new book TCPL 4th edition

本文关键字:4版 3节 片段 TCPL 新书 Stroustrup 难理解 先生      更新时间:2023-10-16

我在理解作者在新书《The C++ Programming Language 4th edition》的3.3.3 Resource Management节中试图传达的内容时遇到了问题。我在下面复制了作者主页上的参考部分:

3.3.3资源管理[tour2.copy.Resource]

通过定义构造函数、复制操作、移动操作和析构函数程序员可以完全控制所包含资源的使用寿命(例如容器的元素)。特别是,move构造函数允许简单而廉价地从一个范围移动到另一个范围的对象。这样,我们可以将我们不能或不想复制的对象移出范围。考虑表示并发活动的标准库线程(§5.3.1)和一个向量的一百万倍。我们不能复制前者,也不想复制后者。

std::vector<thread> my_threads;
Vector init()
{
    thread t {heartbeat}; // run heartbeat concurrently (on its own thread)
    my_threads.push_back(move(t)); // move t into my_threads
    Vector<double> vec;
    // ... fill vec ...
    return vec; // move res out of run()
}
auto v = init(); // start heartbeat and initialize v

这使得资源句柄(如Vector和线程)成为一种替代方案在许多情况下使用指针。事实上,标准图书馆的市场指针"(如unique_ptr)本身就是这样的资源句柄(§5.2.1)。我使用了标准库向量,因为我们无法使用元素类型参数化Vector,直到§3.4.1。

也许我的问题应该是:函数init()内部的vector my_threadsVector vec之间有什么关系?例如,当遇到下面这样一个更简单的替代方案时,上面的代码的优势是什么:

std::vector<thread> my_threads;
thread t(hearbeat);
my_threads.push_back(move(t));
Vector<double> vec;
// ... fill vec ...

函数init()内部的vector my_threadsVector vec之间有什么关系?

两者都说明了您何时需要移动语义。在第一种情况下,你不能将std::thread复制到my_threads中(因为类是不可复制的),但你可以移动它。在第二种情况中,你可以复制一个巨大的向量,以便从函数中返回它,但你不想这样做,因为移动效率高得多。

当面对更简单的替代时,上面的代码有什么优势

更简单的版本没有演示将对象从函数中移出,这正是作者想要演示的。