专栏名称: CPP开发者
伯乐在线旗下账号,「CPP开发者」专注分享 C/C++ 开发相关的技术文章和工具资源。
目录
相关文章推荐
大数据与机器学习文摘  ·  突发!o3-mini ... ·  2 天前  
大数据分析和人工智能  ·  20个很强的DeepSeek提问公式 ·  3 天前  
闹闹每日星运  ·  星历0207:巨蟹谨慎而低调 摩羯剔除不良习惯 ·  3 天前  
软件定义世界(SDX)  ·  与孙正义对话,Sam ... ·  5 天前  
数据派THU  ·  【ICLR2025】AdaWM:基于自适应世 ... ·  5 天前  
51好读  ›  专栏  ›  CPP开发者

C++26's Placeholder variables with no name

CPP开发者  · 公众号  ·  · 2024-04-08 11:50

正文


乘暇再更一个 C++26 的小特性,动机简单,考虑以下例子:
1using Point3D = std::tuple<floatfloatfloat>;
2
3int main() {
4    auto [x, y, z] = Point3D(123);
5
6    return x;
7}

y z 皆未使用,可仍旧要起一个名称,实显多余。新特性允许使用 _ 作为占位符,忽略不关心的值。于是可以这样写:

1using Point3D = std::tuple<floatfloatfloat>;
2
3int main() {
4    auto [x, _, _] = Point3D(123);
5
6    return x;
7}

除了 Structured binding ,RAII 也是一个常用的场景。

1int main() {
2    std::mutex mtx;
3    std::lock_guard _(mtx);
4    std::ifstream _;
5    std::unique_ptr<int> _;
6}

允许重定义,所以全部写在一起也不会存在问题。但是,重定义之后无法使用,Name Lookup 会出现歧义。

 1void g() {
2    int _;
3    _ = 0// OK
4    int _; // OK, name independent declaration
5    _ = 0// error: two non-function declarations in the lookup set
6}
7
8void h () {
9    int _; // #1
10    _ ++;  // OK
11    static int _; // error: conflicts with #1 because static variables are not
12                  // name-independent
13}
14
15int main() {
16    int _{}; // equivalent to [[maybe_unused]] int _;
17    float _{};
18    double _{};
19    char _{};
20
21    return _; // ambiguous
22}

这个占位符本身的目的就是避免为不准备使用的变量命名,所以这不是问题。此外,使用 _ 还会隐式 [[maybe_unused]] ,因此编译器不会给出任何警告。

需要注意,允许使用这种占位符命名的变量,包含 automatic storage duration 、非静态成员变量、 Structured binding lambda capture 。其他情况并不满足,比如 NTTP requires clause 参数名和函数参数。

一个例子:

 1namespace a {
2    auto _ = f(); // Ok, declare a variable "_"
3    auto _ = f(); // error: "_" is already defined in this namespace scope
4}
5void f() {
6    auto _ = 42// Ok, declare a variable "_"
7    auto _ = 0// Ok, re-declare a variable "_"
8    {
9        auto _ = 1// Ok, shaddowing
10        assert( _ == 1 ); // Ok
11    }
12    assert( _ == 42 ); // ill-formed: Use of a redeclared placeholder variables
13}
14
15int main() {
16
17}

这里也出现了 Names shadow,和重载决议里面提到的意义相同,所以它能够访问。

这个小特性并不稀奇,其他语言中早已有之。比如 Python:

1






请到「今天看啥」查看全文