为什么覆盖和最终标识符具有特殊含义而不是保留关键字?

Sha*_*our 29 c++ keyword c++11

在C++ 11中添加了override说明符final说明​​符.它们与添加到C++ 11中的其他说明符(例如constexprdecltype)不同,因为它们不是关键字,因此可用作标识符:

int main()
{
  int override = 0 ;    // Ok
  int final = 0 ;       // Ok
  //int constexpr = 0 ; // Error
}
Run Code Online (Sandbox Code Playgroud)

它们被称为具有特殊含义的标识符,在C++ 11标准部分2.11 [lex.name](强调我的)草案中有所涉及:

表3中标识符在出现在特定上下文中时具有特殊含义.当在语法中引用时,显式地使用这些标识符而不是使用标识符语法生成.任何关于给定标识符是否具有特殊含义的歧义都被解析为将该标记解释为常规标识符.

表3 - 具有特殊含义列表的标识符覆盖最终.

为什么这两个说明符最终成为具有特殊含义的标识符而不是关键字

Sha*_*our 35

添加新关键字很困难,因为它会从用户那里拿走标识符.它最终被选择,目前使用的标识符或选择是非常不可能打破旧的代码,但名称可能会破坏旧代码标识符之间的权衡或没有意义的正在使用他们的方式.

在这种特定情况下,覆盖最终结束在语法中使用的地方没有用户标识符可以出现.因此,在那些地方,标识符可以具有特殊含义,并且在这些上下文之外,它们可以被视为常规标识符,从而使标识符可供用户使用.C++/CLI从那时起就使用了这种技术2005,它们被称为上下文相关关键字,在C++/CLI标准部分9.1.1标识符中有所涉及.

我们可以在文章中看到,解决了在N3163中添加对虚拟控制属性的支持的不同方法的权衡:使用上下文关键字覆盖控制.它讨论了三个选项:

  • 使用[[attributes]],被认为是不受欢迎的原因,包括它们只是伪装的关键词(以下论文中的修改示例):

    class A : public B {
      virtual void f [[override]] () { ... }
      virtual void h [[final]] () { ... }
    };
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用保留关键字,这可能会破坏现有代码,除非选择了丑陋的名称(修改后的例子如下):

    class A : public B {
      virtual void f override_func () { ... }
      virtual void h final_func () { ... }
    };
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用上下文相关的关键字,它不会破坏现有的代码,允许使用漂亮的名称(修改后的例子如下):

    class A : public B {
      virtual void f() override { ... }
      virtual void h() final { ... }
    };
    
    Run Code Online (Sandbox Code Playgroud)

本文的以下段落总结了使用上下文敏感关键字而不是其他两个选择的论点(强调我的):

在Rapperswil中观察到这种方法可以使错误恢复和语法突出显示更加困难.例如,语法突出显示有点困难,因为不是全局突出显示关键字,而是需要进行解析以了解标识符是否位于具有特殊含义的位置并应突出显示.但这并不是特别困难,特别是与其他语言相比,我们在C++中已经不得不做的其他更困难的事情.

这些对于一些编译器编写者来说是一个小小的不便,但对用户来说是无缝的.这是正确的权衡.否则,在属性(选项1)上使用丑陋的全局保留名称(选项2)或不恰当且明显地用螺栓固定 - 使一些编译器编写者在一周内更容易,但是数百万用户必须永远忍受的事情.

通过N3206将更改应用于标准:覆盖控制:消除属性N3272:覆盖控制的后续操作.