2014-10-29 11 views
3

最近我看到很多关于泛型编程的材料,在设计类型时,我仍然无法将自己的头围绕在一件事上。我不确定什么是最好的方式,让我解释一下。类型设计:值类型,默认构造性,可选<T>及其关系?

对于某些类型,提供默认构造函数是很自然的。 该类型的所有可能的构造都是有效的,或者默认是有意义的,所以提供默认值是有意义的。基本类型就是这种情况。

后来,有一些类型的默认构造它们不会产生一个值。例如,在标准库中,我们有std::function<Sig>std::thread。尽管如此,即使它们没有价值,它们也是默认构造的。

后来我们在标准中提出了optional<T>。将它用于基本类型非常有意义,因为对于基本类型,所有可能的赋值都表示一个有效值(双精度和浮点型NaN除外),但我不知道如何将它用于threadstd::function<Sig> ,因为这些类型在构建时不具有“价值”。它是AS,如果这些类型直接嵌入类型的“可选”。

这有这些缺点。由于没有“自然”默认(或价值)建设,如用一个int:

  • 现在我要我的垃圾类在我所有的设计if (valid)和信号错误。或
  • 使它不太安全使用,如果我不做这个检查。先决条件 - >在使用前分配,如果默认构造。

所以当我想要设计一个类型时,我总是会发现这样一个问题:我应该使它成为默认可构造的吗?

优点:

  • 容易重新在更一般的环境中,因为我喜欢的类型会更容易建模半规则或规则,如果我补充此时,相应的操作。

缺点:

  • 产仔了全班同学if陈述或作出与该班是更不安全了用户的使用合同。

例如,假设我有一个带有ID,艺术家,标题,持续时间和年份的类Song。标准库使类型默认可构造是非常好的。但是:

  • 我不能找到构建“默认歌曲”的自然方法。
  • 我得乱抛垃圾if (validsong)或使它不安全使用。

所以我的问题是:

  1. 我应该怎样设计一个没有“天然(在价值上)”默认类型?我应该提供一个默认的构造函数吗?

  2. 在我选择提供默认构造函数的情况下,optional<T>如何适应所有这个难题?我的观点是,使一个不是“自然”默认构造的类型提供一个默认的构造函数,使optional<T>在这种情况下无用。

  3. optional<T>optional<T>只适用于值域完整的类型,也就是说,我不能为它的表示赋一个无效值,因为它们都有一个值,比如int?

  4. 为什么像std::function<Sig>这样的类型在标准的第一位默认构造?构造时,它不具有值,所以我不明白为什么应该提供默认的构造函数。例如,您始终可以这样做:optional<function<void()>>。这只是一个设计选择,两者都是有效的,或者有一种设计,在这种情况下,选择默认与非默认构造优于其他构造?

+0

其实,我对斯捷潘诺夫和肖恩家长对这些问题的看法非常感兴趣。任何材料?没有完成阅读编程元素,也许答复在那里。 – 2014-10-29 06:17:49

回答

1

(注意:在一个问题,有很多的问题,一个问题是,它的某些部分可以重复最好问一下小问题,检查每个事先上岗“每个问题一个问题”是良好的政策,说起来容易做,有时,我猜)

  • 为什么类型,如标准放在首位的std ::功能做出缺省构造?构造时,它不具有值,所以我不明白为什么应该提供默认的构造函数。例如,您始终可以这样做:optional<function<void()>>
  • Why do std::function instances have a default constructor?

    1. 我应该如何设计一个没有 “天然(在价值上)” 默认类型?我应该提供一个默认的构造函数吗?

    为有一个艰难的时间有意义的定义本身没有某种数据类型的默认构造函数是一个很大的类如何实现一个空值。可选是更好的选择?我通常这么认为,但我假设你知道std::optionalvoted out of C++14。即使它是完美的答案,它也不是每个人的答案......它不是汤。

    它会一直增加一些开销来做运行时跟踪,如果该值是绑定或不。开销也许不是lot。但是,当你使用的是一种语言,其存在的理由是允许抽象,同时仍然让你在足部靠近金属的地方自由射击......在巨型矢量中削减每个字节的字节可能很重要。

    因此,即使optional<T>语义和编译时检查是完美的,您仍然可能面临一种情况,即放弃它并允许您的类型编码自己的无效性。得推这些像素或多边形或数据包或... pfafftowns。

  • 在我选择提供一个默认的构造函数的情况下,如何做可选嵌入所有这个难题?我的观点是,使一个不是“自然”默认constructible的类型提供一个默认的构造函数使得在这种情况下可选无用。我可以为它的表示分配一个无效的值,因为它们都有一个值(除了float和doubleNN,我猜)。

  • 就我自己来说,我发现自己想在编译时间,来区分,可以处理空指针的程序和那些不能与检查。但突然有一个optional<pointer>提供了这种情况,可选的是未绑定的,被绑定到空指针,并被绑定到非空指针。编译时的完整性检查看起来不像它赢得的那样。

    那么如何选择参考?他们有争议,最后我听说他们是延迟std :: optional从C++ 14的一组事物中的一个关键点。在将可选指针转换为可选引用之后,这有点令人讨厌。 : -/

    我有一个模糊的想法,写一本关于“病态C++”的书,在那里你选择一些想法,并开始把它的逻辑结论。 optional<T>是我基于您确定的原则而开展的一次尝试。消除在类型本身编码“无效”的可能性,然后突然你可以让编译器进行类型检查,以确定给定位的代码是否准备期望为null。

    (这些天,我向怀疑倾向,如果你得到非常挂了这种“病态C++”,你会风重塑哈斯克尔: - 。/见流行Data.Maybe单子)

    +0

    我认为这些问题如此密切相关,如果我将它们分开,实际上我会忽略这一点。您必须将其视为“所有相关事物” - >默认构造,可选,规则和折衷。 – 2014-10-29 04:57:33

    +0

    @GermánDiago当然......我们可以看到所有编程都是相关的,所以StackOverflow上的所有内容都指向*一个大问题*。这就是为什么Q&A所面临的挑战是要将这个重大问题分解成可独立重用的机构知识。很像软件中的挑战。 *“建筑的本质就是压制对手边工作没有必要的信息,因此建筑学的本质就是这样:它从来不向我们展示其整个自我,而只是一个方面或两个方面时间。“* :-) – HostileFork 2014-10-29 05:08:36

    +0

    感谢您的建议。我有强烈的意见,在这种情况下,它现在是有道理的。 – 2014-10-29 06:01:48

    相关问题