C++26:Std:Is_within_lifetime

发布: (2026年2月19日 GMT+8 21:47)
4 分钟阅读

Source: Hacker News

std::is_within_lifetime 是做什么的?

C++26 添加了

bool std::is_within_lifetime(const T* p);

到 “ 头文件中。该函数在常量求值期间检查 p 是否指向当前仍在其生命周期内的对象。

最常见的用例是检查联合体的哪个成员是活动的:

union Storage {
    int    i;
    double d;
};

constexpr bool check_active_member() {
    Storage s;
    s.i = 42;                     // `i` 成为活动成员
    return std::is_within_lifetime(&s.i); // true
    // std::is_within_lifetime(&s.d) 在这里会返回 false
}

特性与命名

只支持 consteval

std::is_within_lifetimeconsteval 的,因此只能在编译期求值时使用。运行时通常需要通过额外的状态来跟踪活动成员;编译器在常量求值之外并不会保留相同的生命周期跟踪信息。

为什么使用指针而不是引用?

函数接受指针而不是引用,以避免临时对象和生命周期延长规则带来的复杂性。指针可以明确表明你正在查询的具体内存位置。

为什么不叫 “is_union_member_active”?

委员会选择了更通用的名称,因为该机制的用途可以超出联合体。它提供了一种在常量求值中查询对象生命周期的通用方式,未来可能会有更多的应用场景。

最初的动机

该提案源于一个具体问题:实现一个占用最小存储空间的 Optional。考虑一种类型,它要么存储一个 bool 值,要么什么都不存,用联合体来节省空间:

struct OptBool {
    union { bool b; char c; };

    constexpr auto has_value() const -> bool {
        // 如何判断 `b` 是活动成员?
        // 当 `c` 为活动成员时读取 `b` 是未定义行为。
    }
};

在运行时可以使用 c 的哨兵值(例如 2)来表示 “无值”。然而在常量求值期间,需要一种不依赖此类技巧的方法来检测活动成员。std::is_within_lifetime 解决了这个问题:

struct OptBool {
    union { bool b; char c; };

    constexpr auto has_value() const -> bool {
        if consteval {
            return std::is_within_lifetime(&b);
        } else {
            return c != 2;          // 运行时的哨兵值
        }
    }

    constexpr bool value() const {
        return b;
    }
};

constexpr 环境下,该函数告诉我们 b 当前是否存活;在运行时我们回退到哨兵检查。

编译器支持

截至 2026 年 2 月,尚无主流编译器实现 std::is_within_lifetime。随着 C++26 实现的成熟,支持将会逐步到来。

结论

C++26 的 std::is_within_lifetime 提供了一个专注于 constexpr 的工具,用于查询对象生命周期,主要用于在不触发未定义行为的前提下确定联合体的活动成员。其设计——指针参数、consteval 限制以及通用名称——在满足当前需求的同时也为未来的可扩展性留下了余地,使得常量求值更加实用且富有表现力。

0 浏览
Back to Blog

相关文章

阅读更多 »

存储代理获取

UPPER 案例 – 第12部分 Raku 中的容器 这是 UPPER 系列的第12部分,记录了 Raku 语法元素的完整写法……

Apex B. OpenClaw,局部嵌入

本地嵌入用于私有记忆搜索。默认情况下,OpenClaw 的 memory search 会将文本发送到外部的 embedding API,通常是 Anthropic 或 OpenAI……