C++ C+中的“Nil”概念+;
你记得在大学本科的算法课上,有一个C++ C+中的“Nil”概念+;,c++,null,C++,Null,你记得在大学本科的算法课上,有一个Nil的概念是非常方便的,任何东西都可以分配给它或与之比较。(顺便说一句,我从来没有读过计算机科学的本科。)在Python中,我们可以使用None;在Scala中没有任何东西(如果我理解正确的话,它是所有事物的子对象)。但我的问题是,我们如何在C++中拥有 nIL/COD>?下面是我的想法 我们可以使用定义单例对象,但我目前的印象是,大多数人一想到这一点就会退缩 或者我们可以定义全局或静态 我的问题是,在这两种情况下,我想不出一种方法可以将任何类型的变量赋值给N
Nil
的概念是非常方便的,任何东西都可以分配给它或与之比较。(顺便说一句,我从来没有读过计算机科学的本科。)在Python中,我们可以使用None
;在Scala中没有任何东西(如果我理解正确的话,它是所有事物的子对象)。但我的问题是,我们如何在C++中拥有<代码> nIL/COD>?下面是我的想法
我们可以使用定义单例对象,但我目前的印象是,大多数人一想到这一点就会退缩
或者我们可以定义全局或静态
我的问题是,在这两种情况下,我想不出一种方法可以将任何类型的变量赋值给
Nil
,或者将任何类型的对象与Nil
进行比较。Python的None
很有用,因为Python是动态类型的;Scala的Nothing
(不要与ScalaNil
,意思是空列表)优雅地解决了这个问题,因为Nothing
是所有事物的子对象。那么C++中有一个优雅的方式拥有<代码> nIL/COD> C++吗?逐字表示,C++类型无关,不共享公共值。
通过使用继承可以实现某种形式的可共享值,但必须显式实现,并且只能对用户定义的类型实现。在C++11中,有一个值nullptr,可以分配给任何指针类型 如果它不是指针类型,它必须在那里。对于特定的值,您可以定义特殊的“我不存在”值,但没有通用的解决方案 如果可能不存在,您的选择是:
- 指向它并使用nullptr指示不存在的值,或
- 保留一个单独的标志以指示存在或不存在(这是
为您所做的),或者boost::optional
- 为此特定用途定义一个特殊值,以表示不存在的值(注意,这并不总是可能的。)
- 静态类型化语言:一旦用类型定义变量,它就会坚持该类型(这意味着您不能分配一个值
,这不是每个类型可以表示的,您可以用其他动态类型化语言(如Python)来做)None
- 具有内置[1]类型且其类型没有公共基础对象的语言:在所有类型的公共对象中,不能有
加上“此类型可以表示的所有值”的语义None
[1] 与Java内置类型不同,Java内置类型都有相应的类继承自
Java.lang.Object
有两个相关的概念,您称之为Nil
:和
单位类型
这是什么代码,在python中,<代码> nulppRtxt < /C>是C++,它只是一个特殊类型,它具有一个单一的值,它传达了这个特定的行为。由于Python是动态类型的,任何对象都可以与<代码> >“< < />代码>”进行比较,但是在C++中,我们只能对指针进行这样的操作:
void foo(T* obj) {
if (obj == nullptr) {
// Nil
}
}
这在语义上与python相同:
def foo(obj):
if foo is None:
# Nil
选项类型
Python没有(或需要)这样的特性,但所有ML系列都有。这是通过C++实现的。这是一个类型安全的封装的概念,即特定对象可以可能有值,或者没有值。这个概念在函数家族中比在C++中更具表现力:
def foo(obj: Option[T]) = obj match {
case None => // "Nil" case
case Some(v) => // Actual value case
}
<>虽然在C++中也很容易理解,但一旦看到它:
void foo(boost::optional<T> const& obj) {
if (obj) {
T const& value = *obj;
// etc.
}
else {
// Nil
}
}
(注意,我们甚至可以将其推广到任何实现操作符!
template <typename T>
bool operator==(const T& t, Nil_t ) { return !t; }
模板
布尔运算符==(常数T&T,Nil_T){return!T;}
,但最好将我们自己限制在明确的情况下,我喜欢指针和选项给你的明确性)
因此:
int*i=0;
在大多数这些语言中,变量不是作为对象的名称实现的,而是作为对象的句柄实现的
这样的句柄可以设置为“不保存任何内容”,而额外开销很小。这类似于C++指针,其中<代码> null ptr>代码>状态对应于“指向任何”。
这些语言通常完全依赖于垃圾收集。垃圾收集和强制间接引用数据在实践中都会对性能产生重大影响,并且它们限制了您可以执行的操作类型
在这种语言中使用变量时,必须首先“跟随指针”才能找到真正的对象
C++中,变量名通常指的是实际对象,而不是引用对象。当你在C++中使用变量时,你可以直接访问它。一个额外的状态(对应于“没”)需要在每个变量中额外开销,C++的一个原则是,你不为你使用的东西付费。
<>在C++中有一些方法可以生成“空”数据类型。这些不同于使用原始指针、使用智能指针或使用类似于std::experimantal::optional的东西。它们都有一种“那里什么都没有”的状态,通常通过获取对象并在
bool
上下文中对其进行评估来检测。要访问实际数据(假设存在),请使用一元<代码
template <typename T>
bool operator==(const T& t, Nil_t ) { return !t; }
int* i = 0;
std::cout << (i == Nil); // true
i = new int(42);
std::cout << (i == Nil); // false