#include
#include
#include
#include <condition_variable>
#include

class MyClass {
public:
MyClass(int num_conds) : conds_(num_conds), mutexes_(num_conds) {
}

private:
std::vector<std::condition_variable> conds_;
std::vector<std::mutex> mutexes_;
};

int main() {
int num_conds = 5;
MyClass my_class(num_conds);

return 0;
}

我的目的是想在类初始化时根据传入的参数设置条件变量容器 cons_和互斥锁容器 mutexes_的大小,并向其中添加对应数量的元素。但是 c++的条件变量不支持拷贝复制,所以不能 push_back 。
这是 newbing 给的一段代码,能编译能跑,请问对吗?

GPT4 这样说的: 你的目标是在类初始化时根据传入的参数设置 conds_和 mutexes_的大小。目前的代码确实做到了这一点。但你提到了关于 std::condition_variable 不支持拷贝构造的问题,这确实是一个问题。然而,你的当前代码不会触发这个问题,因为你在初始化列表中使用了构造函数直接设置了其大小,而没有使用 push_back 。具体来说,这里:MyClass(int num_conds) : conds_(num_conds), mutexes_(num_conds) {}你用的是 std::vector 的"fill constructor",它会创建指定数量的默认初始化的元素。在这种情况下,不涉及拷贝或移动。总结,你的代码是可以编译和运行的,并且它按预期工作。不过,你确实要注意不要试图拷贝 std::condition_variable ,因为它确实不支持拷贝操作。如果需要移动这些对象,那么你可以考虑使用 std::vector<std::unique_ptr<std::condition_variable>>这样的结构,但在当前的代码和需求下,你不需要这么做。

push_back()除了支持拷贝构造外,还支持传递右值引用,就像楼上说的,你可以传递智能指针向 std::vector<std::unique_ptr<std::condition_variable>>中添加元素

#1 牛啊。说的好详细啊。

#2 那我也需要有条件变量的实例。我就是要在初始化时根据参数指定的数量创建条件变量的个数。

除了 push_back ,还有 emplace_back 吧如果以后需要动态添加的话,就 emplace_back

没理解你什么意思,你在构造函数里创建对应数量的实例不就行了

看上去没问题,不支持拷贝的对象在 vector 中也可以构造时一次性初始化。

好像是我想歪了,构造确实没问题,就是没办法再加数据了而已

想起来了,不能 emplace_back ,不能直接追加。我以前遇到过类似的,std::vector<std::atomic>,一样的情况。最后两个解决办法,第一个就是像这里提到的加一层智能指针,第二个办法比较特殊——std::map 的第二个值,不用 insert(),而是中括号直接插入。还有我自己使用过的、改造过的第三方库就有这样的用法,构造时直接初始化。太久没碰都差不多忘了有这回事。

一般像 condition_variable 之类的,如果一定要放在 vector 里的话,用 std::unique_ptr 包一层是更好的,也更常见。优点一是 condition_variable 本身是不支持移动的,所以你的 vector 是没法 grow 的。且用 unique_ptr 包一层,无论是将来移除个别元素还是替换都会更灵活一些。用裸的 std::vector<std::condition_variable>主要是可以利用内存的局部性原理,因为所有的元素是放在一个 array 里的。另外相比用 unique_ptr 包一层,也可以减少一些 heap 碎片。但是在这里,似乎灵活性比这两点会更重要一些。

应该不能 emplace_back 。condition_variable 是不支持 copy 且不支持 move 的。emplace_back 会增加 vector 的 size ,所以是有可能触发 vector 的 grow 的,但是如果里面的元素不支持 move ,它是没有办法完成 grow 的。

没错,不能 emplace_back 。以前我就弄过同样的代码,长时间没碰都快忘了

代码能编译但是不代表是对的,对与错还是要看你的目的是什么。至于 condition_variable 为什么不能 copy 和 move ,需要从多线程安全和操作系统原理理解了

#1 发 AI 生成的内容会被站长 ban ,这是个技术问题,请问你验证过内容正确性吗?

#5 无论怎么 back ,调用的都是拷贝构造函数。条件变量把拷贝构造函数删了,也就是不允许复制。

#9 那你的 vector 里面的元素数量是写死的?还是在初始化时可以根据参数设置?

#10 但是我需要多个条件变量,数量也不想写死。而是能在类实例化时用参数指定。

我回复里不是写了嘛?如果数量不确定,要支持动态的 grow ,用 std::vector<std::unique_ptr<std::condition_variable>>

#18 我的意思是根据参数创建对应个数的条件变量的实例。vector 里的指针不是指向一个条件变量,而是指向参数个条件变量。

我的办法是,std::unique_ptr<std::condition_variable[]>这样在构造函数可以手动初始化,std::make_unique<std::condition_variable[]>(想要设置的数量) github.com/cnbatch/kcptube/blob/main/src/3rd_party/thread_pool.hpp