【问题标题】:Recursive variable declaration递归变量声明
【发布时间】:2017-04-22 11:39:30
【问题描述】:

我刚刚在folly/ManualExecutor.h看到了这个黑魔法

TimePoint now_ = now_.min();

在对整个库源代码进行 grep 处理后,除了这里之外,我还没有在其他任何地方看到变量 now_ 的定义。这里发生了什么事?这实际上是某种递归变量声明吗?

【问题讨论】:

  • 我认为这个问题可以改进,如果您提供了TimePoint 文档的链接(如果在网络上可用),或者添加了TimePoint::min() 的声明(从.h 文件,如果它编译,你必须拥有)。
  • 另一种混淆代码的方法......
  • 看起来有点像java中的Runtime runtime = Runtime.getRuntime();...
  • @MDXF: 是....但是避免重复类型名,如果它需要模板参数或者是合格的,这可能会很长。

标签: c++11 variables recursion folly


【解决方案1】:

该代码很可能等于:

TimePoint now_ = TimePoint::min();

也就是说min()是一个静态方法,使用实例调用它和这样调用它是一样的,实例只是用于确定类型。不涉及任何黑魔法,这只是做同一件事的两种语法。

至于为什么有问题的代码编译:now_已经在该行的左侧声明,所以当它在右侧用于初始化时,编译器已经知道它的类型并且能够调用静态方法.尝试调用非静态方法应该会报错(见下面@BenVoigt 的评论)。

正如您必须编写此问题所证明的那样,问题中的语法并不是最清楚的。如果类型名称 long 可能很诱人,并且在使用初始化程序(问题代码是)的成员变量声明中可能是合理的。在函数内部的代码中,auto 是减少重复的更好方法。

【讨论】:

  • 从编译器的角度来看,这两种写法是等价的。在代码审查中,只有其中一个是可以接受的。我把它留作练习,让读者猜是哪一个。
  • @CodyGray 是的,每个人都知道你对四点邪恶的仇恨。讲道理科迪:有时候::是最好的选择!
  • 非静态情况分析--初始化器的值计算在复制构造函数调用之前排序(此语法为复制初始化),因此构造函数尚未开始执行,因此对象的生命周期已经没有开始。标准的第 3.8 节说:“在对象的生命周期开始之前,但在分配对象将占用的存储空间之后,可以使用引用原始对象的任何 glvalue,但只能以有限的方式使用。程序未定义行为 if:glvalue 用于调用对象的非静态成员函数。"
  • OP引用的代码实际上是一个非静态数据成员,其中auto不可用。
  • @T.C.唔。你能解释更多吗?看起来像方法 static constexpr time_point min(); 对我来说,基于 Mikel F 的回答。
【解决方案2】:

深入代码可知,TimePoint 是 chrono::steady_clock::time_point 的别名,其中 min() 确实是返回最小允许持续时间的静态方法:

http://en.cppreference.com/w/cpp/chrono/time_point/min

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 2014-09-04
    • 1970-01-01
    相关资源
    最近更新 更多