为什么我不能为D中的结构实现默认构造函数?

为什么我不能为D中的结构实现默认构造函数?,d,default-constructor,D,Default Constructor,像这样编写代码 struct S { this() // compile-time error { } } 给我一个错误消息说 结构的默认构造函数只允许使用@disable,不允许使用body。 为什么???这是一个比人们最初想象的要棘手得多的案例 C++中一个重要的有用的特性是,每一个类型(包括所有用户类型)都有一些初始的非垃圾值,这些值可以在编译时进行评估。它用作T.init,有两个重要的用例: 模板约束可以使用T.init值检查是否可以对给定类型执行某些操作(引

像这样编写代码

struct S
{
    this() // compile-time error
    {
    }
}
给我一个错误消息说

结构的默认构造函数只允许使用@disable,不允许使用body。


为什么???

这是一个比人们最初想象的要棘手得多的案例

<> C++中一个重要的有用的特性是,每一个类型(包括所有用户类型)都有一些初始的非垃圾值,这些值可以在编译时进行评估。它用作
T.init
,有两个重要的用例:

  • 模板约束可以使用T.init值检查是否可以对给定类型执行某些操作(引用Kenji Hara的代码段):

  • 除非显式使用
    int i=void
    语法,否则变量总是正确初始化的。不可能有垃圾

  • 鉴于此,出现了一个困难的问题。我们应该保证T-()和T.init是相同的(因为来自C++的许多程序员会期望)或者允许默认的构造,很容易破坏这个保证。据我所知,尽管令人惊讶,但还是决定第一种方法更安全


    然而,讨论不断涌现,提出了各种改进(例如,允许使用可使用CTFE的默认构造函数)。一个是最近出现的。

    它源于D中的所有类型都必须有一个默认值这一事实。有很多地方可以使用类型的
    init
    值,包括默认初始化成员变量和在分配数组时默认初始化数组中的每个值,并且在编译时需要知道许多这样的情况。拥有
    init
    提供了很多好处,但它确实妨碍了拥有默认构造函数

    在使用
    init
    的所有地方都需要使用真正的默认构造函数(否则不是默认构造函数),但在使用
    init
    的许多情况下,允许任意代码运行充其量是有问题的。至少,您可能会被迫使其具有CTFE功能,并且可能是纯的。一旦您开始对它施加这样的限制,很快,您就可以直接将所有成员变量初始化为您想要的(这就是
    init
    的情况),因为您不会从中获得太多(如果有的话),这将使默认构造函数变得毫无用处

    有可能同时拥有
    init
    和一个默认构造函数,但接下来的问题是,何时使用一个构造函数而不是另一个,默认构造函数将不再是默认构造函数。更不用说,对于开发人员来说,何时使用
    init
    值以及何时使用默认构造函数可能会变得非常混乱

    现在,我们可以
    @禁用结构的
    init
    值(这会导致它自己的一组问题),在这种情况下,在任何需要
    init
    的情况下使用该结构都是非法的。因此,可能会有一个默认构造函数,它可以在运行时运行任意代码,但我不知道这样做的确切后果是什么。然而,我确信,在某些情况下,人们希望有一个需要
    init
    的默认构造函数,因此无法工作,因为它已被@disabled(比如声明类型的数组可能就是其中之一)

    因此,正如您所看到的,通过使用D在
    init
    中所做的,它使得默认构造函数的整个问题比其他语言中的问题复杂得多

    获取类似于默认构造的内容的正常方法是使用静态
    opCall
    。差不多

    struct S
    {
        static S opCall()
        {
            //Create S with the values that you want and return it.
        }
    }
    
    然后,无论何时使用
    S()
    -例如

    auto s = S();
    
    然后调用static
    opCall
    ,得到一个在运行时创建的值。但是,
    S.init
    仍将在以前的任何位置使用(包括
    S;
    ),并且只有在显式使用
    S()
    时才会使用静态
    opCall
    。但是,如果将其与禁用this()
    (禁用
    init
    属性)相结合,那么您将获得类似于我前面所述的内容,其中我们可能会使用带有@disabled
    init
    的默认构造函数

    我们最终可能会也可能不会将默认构造函数添加到语言中,但由于
    init
    和语言的工作方式,添加默认构造函数时会出现一些技术问题,Walter Bright认为不应该添加默认构造函数。因此,对于要添加到语言中的默认构造函数,必须有人提出一个真正令人信服的设计,该设计可以适当地解决所有问题(包括说服Walter),我不希望发生这种情况,但我们拭目以待

    auto s = S();