复制构造函数是一个构造函数,它创建一个新对象,它是现有对象的克隆。该术语主要用于C ++编程语言,其中复制构造函数具有特殊状态。
我知道 atomic 有一个被删除的复制构造函数,但是我该怎么做才能使这段代码工作?我怎么可能在原子向量中定义一个复制构造函数? #包括 我知道 atomic 有一个被删除的复制构造函数,但是我该怎么做才能使这段代码工作?我怎么可能在向量中为原子定义一个复制构造函数? #include <atomic> #include <vector> int main() { std::vector<std::atomic<int>> examp; examp.resize(64); } 你不能有 std::atomic<int> 的向量,因为它不可复制或移动,但你可以有一个 unique_ptr 到 atomic<int> 的向量。如果你真的需要一个运行时可变大小的原子向量,这可能是一个可行的选择。这是一个例子: #include <iostream> #include <atomic> #include <vector> #include <memory> using namespace std; int main() { std::vector<std::unique_ptr<std::atomic<int>>> examp; examp.resize(64); // 64 default unique_ptrs; they point to nothing // init the vector with unique_ptrs that actually point to atomics for (auto& p : examp) { p = std::make_unique<std::atomic<int>>(0); // init atomic ints to 0 } // use it *examp[3] = 5; for (auto& p : examp) { cout << *p << ' '; } cout << '\n'; } std::atomic 不可复制或移动。正如您所指出的,复制构造函数被删除但没有生成移动构造函数。见http://en.cppreference.com/w/cpp/language/move_constructor: 如果没有为类类型提供用户定义的移动构造函数 (结构、类或联合),并且以下所有为真: 没有用户声明的拷贝构造函数; 用户声明的意思是“编译器没有添加”(即由default)。尽管它是一个库类,但构造函数是用户声明的。 矢量的 resize 函数要求类型是可移动插入或可复制插入的,具体取决于重载。见http://en.cppreference.com/w/cpp/container/vector/resize: 如果当前大小小于计数, 1)附加默认插入的元素 2)附加值的额外副本 你所做的根本行不通。 我在 VS 2022 中尝试了以下代码并且它有效: #include <atomic> #include <vector> int main() { std::vector<std::atomic<int>> examp (64); } 但是,由于std::atomic类型不可复制不可移动,所以一些成员函数(如resize())无法实现。对于原子变量的向量,许多成员函数提出了更严格的要求。 见https://en.cppreference.com/w/cpp/container/vector 如果你只需要一个运行时变量的大小,但之后不需要调整对象的大小,你可以使用 std::vector< atomic<int> > elems(size) 正如@Quanbing Luo 指出的那样。 像.pop_back和.push_back这样的成员函数不会编译,即使你已经安排好了它绝对不会超过它的.capacity()并且必须增长。但除此之外它应该工作正常。 在 C++20 中,您可以使用 std::atomic_ref 对普通 int 对象进行原子操作,因此您可以使用 std::vector<int> 和 static_assert(std::atomic_ref<int>::required_alignment == alignof(int), "vector elements need to be sufficiently aligned for atomic_ref"); std::vector<int> examp(size); // and potentially do whatever non-atomic init before sharing examp.resize(size2); std::atomic_ref<int> examp3(examp[3]); examp3.store(1, std::memory_order_release); 也许到处都使用typedef或其他东西而不是裸露的int。甚至可能是一些原子操作的辅助函数,因此您不必在单独的语句中手动构造 atomic_ref 对象。 (构造一个是免费的;只要您不保留 atomic_ref 对象,它就会优化。它仅作为 API 存在,用于包装像 GNU C __atomic_load_n(int *, int memorder) 这样的东西,您可以手动使用它,如果你不想使用 C++20 特性。) 当其他线程正在访问它的元素时,没有什么可以使它线程安全地增长或缩小向量,所以在另一个答案中提出的额外间接级别没有任何好处std::vector<std::unique_ptr<std::atomic<int>>> examp;。std::vector<unique_ptr>对象本身(通常 3 个指针,.data()、.end() 和分配结束)不是原子的,任何在另一个线程访问它时重新分配数组的东西都是一个问题。 编写低效代码只是为了让编译器满意,这与使用无锁原子而不是锁定(以牺牲简单性为代价的性能)的目的有点不一致。
我有以下代码: C类{ 民众: C(整数){} C(常量 C&) {} C() {} }; D类:公共C { 民众: 使用 C::C; }; 诠释主要(){ CC; D d_from_c(c); //...
我必须使用复制构造函数和复制赋值运算符来测试链表。 list1 附加了 3 个双打 list2 = list1 复制构造函数进来的地方。 List4 = list3 = list1 是...
这是简单的代码片段。我想要 I-A-B 类继承,这样我的复制构造函数也可以初始化从 I 继承的派生类的就地虚拟表。 为简单起见...
如何在 C++17 中禁用过于通用的转发构造函数并推迟到复制构造函数
如果我有使用 c++20 概念编写的简单类 #包括 #包括 模板 结构 MyVec { std::array m_vec;
我正在尝试为 A 类使用自定义哈希结构,它是 std::unordered_map 中的键类型,它是 B 类中的 std::variant 替代方案之一。 这是我的代码的简化版本,其中...
c++ 编译器可以在用户定义的和编译器生成的复制构造函数之间自由选择?
我有以下示例代码(我程序的精简版) 类“some_class”有一个带有默认参数的构造函数。编译器能够将此构造函数识别为副本
我是 c++ 的新手,正在学习教程(将在下面链接)并且遇到了此类构造函数: 玩家类:公共实体 { 私人的: std::string m_Name; 民众: 播放器(
我正在制作一个程序来确定一条推文是快乐还是悲伤,我想我对推文进行标记,然后创建一个映射,将这个词存储为键,总共使用了多少次,a。 ..
不能使用 std::map::emplace 插入没有复制构造函数的类的对象
我正在尝试编译以下代码: #包括 #包括 我的班级 { 民众: 我的类():m_cv(){} std::condition_variable m_cv; //只是为了说明...
根据 abseil.io/tips/177,它说 具体来说,如果您的班级有 const 成员,则无法将其分配给(无论是通过复制分配还是移动分配)。语言理解这一点:如果...
为什么将捕获的 lambda 分配给 std::function 会导致更多副本[重复]
在下面的代码中,分配给 std 函数比分配给自动变量导致更多的复制构造函数调用。 (实际上是初始化,而不是分配;)) 我得到了一个捕获的值
将使用 packaged_task 的 lambda 任务放入队列中
所以我有一个线程池的入队实现 模板 自动排队(F&& f, Args&&... args) -> std::future 所以我有一个线程池的入队实现 template <typename F, typename... Args> auto enqueue(F&& f, Args&&... args) -> std::future<decltype(f(args...))> { using return_type = decltype(f(args...)); auto task = std::make_shared<std::packaged_task<return_type()>>( std::bind(std::forward<F>(f), std::forward<Args>(args)...) ); auto result = task->get_future(); { std::unique_lock<std::mutex> lock(m_queue_mutex); if (m_stop) throw std::runtime_error("enqueue on stopped ThreadPool"); m_tasks.emplace([task]() { (*task)(); }); } m_condition.notify_one(); return result; } 到目前为止一切顺利,但我想避免使用内存分配而不使用 make_shared。 所以我改成这样: template <typename F, typename... Args> auto enqueue(F&& f, Args&&... args) -> std::future<decltype(f(args...))> { using return_type = decltype(f(args...)); auto task = std::packaged_task<return_type()>( std::bind(std::forward<F>(f), std::forward<Args>(args)...) ); auto result = task.get_future(); { std::unique_lock<std::mutex> lock(m_queue_mutex); if (m_stop) throw std::runtime_error("enqueue on stopped ThreadPool"); m_tasks.emplace([task = std::move(task)]() mutable { task(); }); } m_condition.notify_one(); return result; } 据我所知,这里没有copy。 任务应该移到 lambda 中,lambda 应该移到队列中,但我仍然收到此错误 使用删除函数‘std::packaged_task<_Res(_ArgTypes ...)>::packaged_task(const std::packaged_task<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]' 38 | m_tasks.emplace(任务可变{任务();}); 我的理解是我正在尝试复制 packaged_task 并且它的复制构造函数被删除了。 在这里你可以玩完整的代码 https://godbolt.org/z/bEsPfabz6 谢谢!
一个简单的复制交换设置。constmem有一个名为x的const成员,当使用复制-赋值操作符时,看起来x将未被初始化,但不知为何却被复制了......。
怎么会出现调用了destructor,但之前没有constuctor呢?
我目前正在学习c++的面向对象特性。我写了一段代码来测试继承和多态是如何工作的。下面是部分代码: class Person { public: ...
下面的代码会导致分段故障,但我不明白为什么。#include #include #include class State {public:int x; int y; State(int _x, ...
如何在Bullet Physics中深度复制一个btTriangleMesh?
我使用Bullet Physics,我需要复制一个btTriangleMesh类型的实例。/ 变量是一个类成员btTriangleMesh triangles; 我的目的是将一个体的碰撞形状改变为一个新的 ...
当我在阅读。赋值操作符和复制构造函数的区别是什么?赋值运算符和复制构造函数的区别是什么?下面的...
我的.h文件中给了我一个Node和Stack类。我必须实现复制构造函数、赋值操作符和析构器,并在不同的测试文件中测试它们。当测试复制 ...