move-semantics 相关问题

移动语义是一种编程语言功能,当源对象是临时对象或其他过期对象时,允许复制操作被更有效的“移动”替换。

在 C++03 编译器上使用移动模拟将 boost::unique_lock 作为返回值从函数中移出是否安全?

我有以下可移动但不可复制的类,可用于同步对某些共享资源的访问: 类wrapper_with_lock{ 私人的: BOOST_MOVABLE_BUT_NOT_COPYABLE(

回答 1 投票 0

有没有办法从采用右值引用的构造函数调用移动构造函数? [重复]

假设我有一个带有移动构造函数的 A 类: A类{ 民众: A(A &&other) = 默认值; } 假设我有一个包含 A 成员的类: B类{ 一个一个; } 第一部分

回答 1 投票 0

如果在 C++ 中使用仅移动类型的容器的复制构造函数,会发生什么? [已关闭]

如果在 C++ 的容器中使用可移动但不可复制的类型,例如 unique_ptr, 然后使用依赖于副本的函数,例如复制构造函数、范围插入、运算符 = (&) 或...

回答 1 投票 0

使用 std::move 返回 std::vector [重复]

我有一个非常基本的问题:使用 std::move 返回 std::vector 是一个好主意吗?例如: A类{}; std::vector && func() { std::向量 v; ...

回答 3 投票 0

从函数返回值时使用 std::move() 以避免复制

考虑支持默认移动语义的类型 T。还要考虑下面的函数: Tf() { Tt; 返回t; } To = f(); 在旧的 C++03 中,一些非优化编译器可能会调用 c...

回答 3 投票 0

当我们使用右值引用时到底会发生什么以及 std::move 是如何工作的? [重复]

我正在尝试理解右值引用和移动语义。在下面的代码中,当我将 10 传递给 Print 函数时,它会调用右值引用重载,这是预期的。但到底发生了什么,w...

回答 3 投票 0

复制按值返回的对象和移动它有什么区别?

我想知道将函数的返回值移动到 std::string 对象而不是直接复制它是否有任何意义? “ip_str”是应该获得...的返回值的对象

回答 1 投票 0

无法移动 std::any

以下代码 使用 vptr = std::vector>; 自动 m = std::unordered_map{}; m.try_emplace(0, 移动(vptr{})); 编译失败,抱怨...

回答 1 投票 0

GameState 的 C++ 移动语义

我的任务是在 C++ 中为机器人游戏实现移动语义(移动构造函数和移动赋值运算符)。 我收到一些反馈说我应该从其他人那里“窃取”资源...

回答 1 投票 0

使用 `{}` 构造 std::tuple 时,Clang-Tidy 对于 std::move 是否正确?

我正在用 C++ 实现一个函数,特别是一个可调用的类对象,旨在返回一个包含对象容器和结果的 std::tuple。经过一些调整(见下文)我......

回答 1 投票 0

看起来 std::move_iterator 只适用于字符串数据类型

如果容器具有字符串类型的数据,则可以使用 std::move_iterator 将数据从源容器移动到目标容器。 std::move_iterator 不与其他数据一起操作

回答 1 投票 0

如何将 rust 结构“转换”为另一个相同类型(相同的字段/布局)而不复制所有成员

我在一个模块中有一个私有类型,它与另一种类型具有相同的字段。我无法相互导入(以某种方式共享类型),因为这会导致循环依赖,而且会非常

回答 1 投票 0

在模式匹配期间防止移动语义

我这里有一个愚蠢的例子,只是为了演示我在使用另一个库和模式匹配时遇到的问题。 结构人{ 名称: 字符串, 年龄:i32, 选择:选择 } #[推导(

回答 2 投票 0

我应该始终继续使用 `sink` 构造函数或 setter 参数吗?

结构 TestConstRef { std::字符串str; 测试(const std::string& mStr) : str{mStr} { } }; 结构测试移动{ std::字符串str; 测试(std::string mStr) : str{std::move(mStr)} { } }; ...

回答 2 投票 0

C++11 移动语义行为特定问题[重复]

我已阅读以下文章,它对移动语义有了很好的了解: 有人可以向我解释一下移动语义吗? 但我仍然无法理解以下关于我的事情...

回答 2 投票 0

标准算法的 lambda 应该接受什么样的参数?

所以我昨天在 youtube 上观看 C++ 视频,遇到一个关于 C++-11 右值引用和移动语义的视频。我想我从广义上理解了这个概念,但是今天当我...

回答 1 投票 0

为什么添加默认的移动赋值运算符会破坏标准交换函数的编译?

在下面的代码中,如果移动赋值未注释,则交换函数将停止程序的编译。我在所有 3 个主要编译器(GCC、Clang、MSVC)上观察到了这种行为。 #包括 在以下代码中,如果未注释移动分配,则交换函数将停止程序的编译。我在所有 3 个主要编译器(GCC、Clang、MSVC)上都观察到了这种行为。 #include <utility> #include <memory> struct test { test() = default; test(test&& other) noexcept = default; //test& operator=(test&& other) noexcept = default; test(const test& other) : ptr(std::make_unique<int>(*other.ptr)) {} test& operator=(test other) noexcept { std::swap(*this, other); return *this; } std::unique_ptr<int> ptr; }; Godbolt 测试:https://godbolt.org/z/v1hGzzEaz 研究标准库实现,他们使用 SFINAE 或概念来启用/禁用 std::swap 重载,并且当特殊函数未注释时,由于某种原因,某些特征会失败(libstdc++ 上的 is_move_constructible 和/或 is_move_assignable)。 我的问题是:为什么添加默认的特殊成员函数会阻止标准库将类型视为可移动? std::move的主要实现在内部使用移动分配,类似于。 template <typename T> void swap(T& a, T& b) { T c = std::move(a); a = std::move(b); b = std::move(c); } 这意味着移动分配需要对您的类型有效,但事实并非如此。 如果你调用移动赋值运算符,你会得到一个错误: <source>:18:15: error: use of overloaded operator '=' is ambiguous [...] [...] | <source>:9:11: note: candidate function 9 | test& operator=(test&& other) noexcept = default; | ^ <source>:15:11: note: candidate function 15 | test& operator=(test other); | ^ 这两个运算符都可以使用 xvalue 进行调用,并且两者都不是更好的匹配。 std::swap 受到限制,因此只有 MoveAssignable 类型可以交换,而你的类型则不能。 即使你可以打电话std::swap,你也不能同时打电话 依赖 std::swap 的默认实现,它使用 operator= 用 operator= 定义 std::swap 这将是无限递归,因为 = 和 std::swap 的定义是循环的。 解决方案 您可以为您的类型定义自定义 swap,这样您就不再依赖 std::swap。 只保留 operator=(test),看起来像: test& operator=(test other) noexcept { swap(*this, other); // custom function, not std::swap return *this; } 您还可以手动定义单独的 operator=(const test&) 和 operator=(test&&) ,以便 std::swap 将使用移动赋值运算符,并且重载决策中不会有歧义。

回答 1 投票 0

std::move 和 std::shared_ptr 参数按值传递

考虑以下代码: #包括 #包括 班级测试 { 民众: 测试(int t):t(t){} 整数t; }; 无效测试(std::shared_ptr t) { 标准...

回答 1 投票 0

为什么C++中的移动语义在函数签名中有右值引用

考虑下面的移动赋值运算符: 类我的类{ 私人的: ssize_t buf_size; 无效* buf_ptr; 民众: MyClass &operator=(MyClass &&rhs) { 如果(这个!= &rhs){

回答 1 投票 0

编译器可以删除特定数据成员的副本吗?

获取此代码: struct Bar { //有非默认的复制构造函数 酒吧()=默认; 酒吧(常量酒吧&){} }; struct LargeObject { //有默认的复制构造函数 std::数组 获取此代码: struct Bar { //has non-default copy-constructor Bar() = default; Bar(const Bar&) {} }; struct LargeObject { //has default copy-constructor std::array<char, 1000> m_chars; }; struct Foo { Bar m_bar; LargeObject m_obj; }; Foo func() { Foo f; return f; } 当用户指定复制构造函数时,编译器无法删除副本。当类的成员具有非默认复制构造函数时该怎么办?在此代码中,当从 f 返回 func 时,编译器是否可以删除 m_obj 的副本,还是必须复制所有内容? 你的问题是基于一个错误的前提。编译器完全有权删除这样的副本,无论类本身或其成员之一是否具有非默认复制(或移动)构造函数。自 C++11 以来引入的复制省略规则的好处是允许这种优化,即使它违反了 as-if 规则。 如果做不到这一点,复制省略就没有那么有用了;即使只有一个智能指针(具有自定义复制和移动构造函数)的类也没有资格使用 RVO,除非编译器可以肯定地证明没有违反 as-if 规则。 在您的特定场景中,编译器可以在启用优化的情况下(这不是强制性的,因为您依赖于非强制性 NRVO,而不是简单 RVO 的 C++17 保证复制省略)通过以下方式实现 func直接将 Foo 对象构建到调用者提供的存储中,而不使用必须移动/复制回调用者的单独 Foo f。

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.