gpt4 book ai didi

c++ - 为什么名称的声明点在其初始值设定项之前?

转载 作者:行者123 更新时间:2023-12-03 06:49:19 26 4
gpt4 key购买 nike

说 C++ 标准:

The point of declaration for a name is immediately after its complete declarator and before itsinitializer (if any)... [basic.scope.pdecl]


也就是说,一个变量在它自己的初始化表达式的上下文中,并且可以被引用。
据我所知,你可以用它做以下类型的事情:
  • int x = x ,这是格式良好但没有意义的。
  • void* p = &p ,这很可爱但没用。
  • std::any a {&a} ,#2 的 C++17 版本。
  • MyClass m {std::move(m)} ,#1 的 C++11 版本,可能还有 UB。
  • MyClass m {myFunc(m)} ,用一个函数来获取你未初始化的对象,我猜它记录在某个地方?并返回一些值,以便构造函数可以试一试。

  • 当然,#1-4 没用。似乎可以构建一个接口(interface),其中#5 有意义,但我看不出它是完成任何事情的最直接的方式。由于在评估初始化程序时新变量尚未初始化,因此读取其值是无用/非法的,并且其地址通常对其初始化并不重要。
    (可以提出一个稍微强一点的情况,将声明点留到初始化器之后: int avg = avg(a,b,c) 。这不是好的代码,对任何事情都不是必需的,但它比 void* p = &p 更有意义。)
    但这不仅仅是用例。通常,C++ 会努力防止对未初始化对象的访问。例如,它一次设置一个对象的 vtable 基类:如果 D 继承自 C 继承自 B,则在 C 的构造函数期间,虚拟方法将被分派(dispatch)给 C 的实现,而不是 D 的实现。可以窥视未初始化对象的常见情况是这种情况,以及(更常见的问题)使用 this在成员初始化表达式中。
    所以我看不到在初始化器之前将名称引入范围内的用途,并且我可以看到将其延迟到初始化器之后的明确理由(Stroustrup 也会看到)。鉴于此,C++ 选择的行为是否有明确的意义?

    最佳答案

    its address isn't generally going to be important to its initialization.

    template <class T>
    struct Node
    {
    Node *prev, *next;
    std::optional<T> data;
    };

    template <class T>
    struct List
    {
    Node<int> sentinel {&sentinel, &sentinel};
    // methods ...
    };
    这是基于标记的双向链表的完全合法且有用的初始化。
    任何类似图的数据结构都可以具有自引用,这可以通过将对象的指针或引用作为参数传递给其自己的构造函数来实现。没有理由禁止这些。
    如果您担心 int x = x; 中固有的未定义行为, 只是 enable warnings (warning: shameless plug)正如你应该做的那样。编译器现在相当擅长捕捉这些东西。

    关于c++ - 为什么名称的声明点在其初始值设定项之前?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64461244/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com