【问题标题】:Translating C++ member initialisation constructor to Julia将 C++ 成员初始化构造函数转换为 Julia
【发布时间】:2020-09-23 12:43:02
【问题描述】:

我在 C++ 中有这个类,并希望在 Julia 中复制它。

class Clock
{
  double epsilon;
  double dt;
  int64_t timestep;
  double t;
  Clock(double _epsilon=1e-14) : epsilon(_epsilon)
};

到现在为止

mutable struct Clock
    epsilon::Float64
    dt::Float64
    timestep::Int64
    t::Float64
    #Need the constructor#
end

【问题讨论】:

  • C++ 如何初始化那些你没有在构造函数中赋值的其他字段?随机,还是零默认值?有没有“未初始化”的概念? (也许在这个问题上加上一点,不是每个人都知道 C++)。
  • 这似乎不是关于翻译,而只是关于如何在 Julia 中编写构造函数和/或表达科学记数法。也就是说,C++ 区分大小写,所以Class Clock 不起作用。 @phipsgabler 未显式初始化的基本字段将具有未定义的值,并且在分配之前无法读取,因此应该通过确保它们始终被初始化来避免这种情况。最简单的方法是在每个成员的名称后添加{},这样可以确保在构造函数没有更具体地对其进行初始化时默认初始化。
  • @underscore_d 如果您不知道其中的微妙之处以及未初始化部分如何从一种语言映射到另一种语言,那么将其称为翻译是合理的(他们在 Julia 中所写的 Clock 是不可变的,如果你不把字段赋值,你永远无法摆脱那些会去那里的随机废话......)
  • 我没有意识到 Julia 有一个未初始化的概念。奇怪的是它默认允许废话是不可变的:-)
  • 不同之处在于未初始化仅对非位类型有意义。 Bitstypes 默认初始化为随机的东西,其他的行为有点像你上面描述的“未定义”(如果你在没有先分配任何东西的情况下访问该字段,你会得到一个错误)。 (就像你说int a 并尝试用a 做某事,只是它没有定义为未定义)。

标签: c++ class struct julia


【解决方案1】:

我认为最接近 C++ 的行为如下:

mutable struct Clock
    epsilon::Float64
    dt::Float64
    timestep::Int64
    t::Int64

    Clock(epsilon=1e-14) = new(epsilon) 
end

剩下的字段incomplete。由于它们具有所谓的bits types,因此它们实际上已被初始化,但具有未定义的值(与 C++ 相反,它们未初始化,IIUC),因此在没有赋值的情况下访问字段不会出错(它适用于非位类型,例如数组)。

结构体必须是可变的,否则在构造值后您无法更改字段,并且永远留下一堆垃圾。

但是可以说,不完全初始化并不是特别惯用的,或者至少要尽可能避免。我宁愿把类型写成如下:

struct Clock
    epsilon::Float64
    dt::Float64
    timestep::Int64
    t::Int64
end

Clock(epsilon=1e-14) = Clock(epsilon=epsilon, 0.0, 0, 0)

(或任何对您有意义的默认值),并坚持使用不可变函数来操作它。第二个变体使用outer constructor,它基本上只是类型上的一个方法(new 和不完整的初始化等特殊内容仅在内部构造函数中可用)。这个外部构造函数调用默认提供的内部构造函数。

【讨论】:

  • FWIW,C++ 中未初始化的原语有一个“未指定的值”,这会导致访问时出现未定义的行为(不是错误),因此这些语义在实践中似乎非常等效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 2020-09-30
相关资源
最近更新 更多