<QtTypeTraits> - Qt 类型特性

类型特性和转换的功能。 更多...

头文件 #include <QtTypeTraits>
Qt 6.5

函数

TqExchange(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公司有限公司的商标。所有其他商标均为各自所有者的财产。