<QtTypeTraits> - Qt 类型特性
类型特性和转换的功能。 更多...
头文件 | #include <QtTypeTraits> |
自 | Qt 6.5 |
函数
T | qExchange(T &obj, U &&newValue) |
(自 6.2) std::underlying_type_t<Enum> | qToUnderlying(Enum e) |
函数文档
[constexpr noexcept(...)]
模板 <typename T, typename U = T> T qExchange(T &obj, U &&newValue)
将 obj 的值替换为 newValue 并返回 obj 的旧值。
这是 Qt 对 std::exchange() 的实现。它仅与 std::exchange() 不同,即在 C++20 之前它已经是 constexpr
,在 C++23 之前已经是 noexcept。
我们强烈建议在不需要 C++20 或 C++23 变体时使用 std::exchange()。
以下是使用 qExchange() 实现 move 构造函数的示例
MyClass(MyClass &&other) : m_pointer{qExchange(other.m_pointer, nullptr)}, m_int{qExchange(other.m_int, 0)}, m_vector{std::move(other.m_vector)}, ...
对于类类型成员,我们可以使用 std::move(),因为它们的移动构造函数将正确执行。但是对于原始指针或整数类型等标量类型,移动与复制相同,这对于指针尤其不是我们希望看到的情况。因此,我们不能为这些类型使用 std::move(),但我们可以使用 std::exchange()/qExchange() 来确保在初始化下一个数据成员之前,源对象的成员已经被重置,这在构造函数异常退出时可能会有用。
以下是使用 qExchange() 编写消耗其迭代的集合的循环的方式
for (auto &e : qExchange(collection, {}) doSomethingWith(e);
这相当于以下更为冗长的代码
{ auto tmp = std::move(collection); collection = {}; // or collection.clear() for (auto &e : tmp) doSomethingWith(e); } // destroys 'tmp'
这对于循环是完全安全的,因为 for 循环将 qExchange() 的结果保持活动状态,直到循环运行完毕,从而避免了临时变量的声明。请注意,尽管如此,qExchange() 返回的是一个非 const 对象,因此 Qt 容器可能会断开连接。
注意:当 "std::conjunction_v<std::is_nothrow_move_constructible<T>, std::is_nothrow_assignable<T &, U>>" 为 true 时,此函数不会抛出任何异常。
[constexpr noexcept, since 6.2]
模板 <typename Enum> std::underlying_type_t<Enum> qToUnderlying(Enum e)
将枚举值 e 转换为其枚举类型中使用的底层类型等效值。
此函数是在 Qt 6.2 中引入的。
© 2024 Qt公司有限公司。此处包含的文档贡献为各自所有者的版权。提供的文档遵循自由软件基金会发布的《GNU自由文档许可证》第1.3版的规定。Qt及其相关标志是芬兰和/或世界其他国家Qt公司有限公司的商标。所有其他商标均为各自所有者的财产。