最近我看到很多关于泛型编程的资料,在设计类型时我仍然无法理解一件事。我不确定什么是最好的方式,让我解释一下。
对于某些类型,提供默认构造函数是很自然的。 该类型的所有可能构造都是有效的,或者默认是有意义的,因此提供默认值是有意义的。这是基本类型的情况。
稍后,有些类型的默认构造它们不会产生值。例如,在标准库中,我们有std::function<Sig>
和std::thread
。然而,它们是默认可构造的,即使它们没有保持价值。
稍后,我们在标准中提出了optional<T>
。将它用于基本类型是很有意义的,因为对于基本类型,所有可能的赋值都代表一个有效值(double和float NaN除外),但我不知道如何将它用于{{1} }或thread
,因为这些类型在构造时不具有“值”。如果AS IF这些类型直接嵌入类型中的“可选”。
这有这些缺点。由于没有“自然”默认(或值)构造,例如使用int:
std::function<Sig>
乱丢我的班级并发出错误信号。 OR 因此,当我想设计一个类型时,我总能找到一个问题:我应该将它设为默认构造吗?
优点:
缺点:
if (valid)
语句乱丢全班,或者与使用该类更不安全的用户签订合同。例如,假设我有一个课程if
,其中包含ID,艺术家,职称,持续时间和年份。标准库使类型默认可构造非常好。但是:
Song
或者使用它不安全。所以我的问题是:
我应该如何设计一个没有“自然(如值)”默认值的类型?我应该提供默认构造函数吗?
在我选择提供默认构造函数的情况下,if (validsong)
如何适应所有这个难题?我的观点是,在这种情况下,使一个不是“自然”默认构造的类型提供默认构造函数会使optional<T>
无用。
optional<T>
只应用于其值域完整的类型,意思是,我不能为其表示分配无效值,因为它们都包含一个值,例如int?
为什么optional<T>
等类型在标准中首先默认构造?构造时,它没有值,所以我不明白为什么应该提供默认构造函数。例如,您可以随时执行:std::function<Sig>
。这只是一个设计选择,两者都是有效的,或者有一种设计,在这种情况下,选择默认与非默认可构造优于另一种?
答案 0 :(得分:1)
(注意:在一个问题中有很多问题的问题是它的某些部分可能是重复的。最好问一些较小的问题,并检查每个问题的先前的帖子。“每个问题一个问题”是一个好的政策;有时说起来容易做起来难,我猜。)
- 为什么诸如std :: function之类的类型在标准中首先默认可构造?构造时,它没有值,所以我不明白为什么应该提供默认构造函数。你可以随时做:
醇>optional<function<void ()>>
,例如。
请参阅Why do std::function instances have a default constructor?
- 我应该如何设计一个没有“自然(如值)”默认值的类型?我应该提供默认构造函数吗?
醇>
对于那些在没有某种数据的情况下有意义地定义自己的类型的类型的默认构造函数是很多类如何实现null值。可选择更好的选择吗?我通常这么认为,但我假设你知道std::optional
是voted out of C++14。即使它是完美的答案,也不是每个人的答案......它还不是汤。
如果绑定了值,它将总是增加一些开销来进行运行时跟踪。也许不是很多的开销。但是当你使用一种语言,其存在的理由是允许抽象,同时仍然让你自己在脚下射击,尽可能接近金属......在巨型矢量中每个值削减一个字节可能很重要。
因此,即使optional<T>
语义和编译时检查完美,您仍然可能会遇到一种情况,即废弃它并允许您的类型编码自己的无效。要推动那些像素或多边形或数据包或...... pfafftowns。
在我选择提供默认构造函数的情况下,可选项如何适应所有这个难题?我的观点是,制作一个不是“自然”默认构造的类型提供了一个默认构造函数,在这种情况下可选择无用。
- 醇>
如果可选的仅用于其值域完整的类型,意思是,我不能为其表示分配无效值,因为它们都包含一个值(浮点数和双NaN除外)。
在我自己的情况下,我发现自己想要区分可以处理空指针的例程和不能处理空指针的例程之间的编译时检查。但是突然有一个optional<pointer>
提供了这样的情况:可选的是未绑定的,绑定到空指针,并绑定到非空指针。编译时的健全性检查似乎没有它的胜利。
那么可选参考怎么样?他们有争议的是,最后我听说他们是延迟std :: optional从C ++ 14延伸的事情中的一个难点。在将可选指针转换为可选引用之后,这有点烦人。 : - /
我有一个模糊的想法,就是写一本关于“病态C ++”的书,你可以从中选择一些想法并开始将其用于逻辑结论。 optional<T>
是我所接受的一次踢,基本上是你所确定的原则。消除在类型本身中编码“nullity”的可能性,然后突然你可以让编译器进行类型检查,以确定给定的代码位是否准备好为null。
(这些天我倾向于怀疑如果你对这种“病态C ++”非常感兴趣,你最终会重新发明Haskell。: - /见流行的Data.Maybe monad。)< / em>的