Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么C++';s空类型只是半心半意的单位类型?_C++_Types - Fatal编程技术网

C++ 为什么C++';s空类型只是半心半意的单位类型?

C++ 为什么C++';s空类型只是半心半意的单位类型?,c++,types,C++,Types,C++的void类型不是无人居住的。问题是,虽然它只有一个居住者,很像ML语言中的单元类型(又称()),但该居住者不能作为普通值命名或传递。例如,以下代码无法编译: void foo(void a) { return; } void bar() { foo(foo()); } 而等价的(比如)Rust代码可以编译得很好: fn foo(a : ()) { return; } fn bar() { foo(foo(())); } 实际上,void就像一个unit类型,但只是半心半意的。为什么会

C++的
void
类型不是无人居住的。问题是,虽然它只有一个居住者,很像ML语言中的
单元
类型(又称
()
),但该居住者不能作为普通值命名或传递。例如,以下代码无法编译:

void foo(void a) { return; }
void bar() { foo(foo()); }
而等价的(比如)Rust代码可以编译得很好:

fn foo(a : ()) { return; }
fn bar() { foo(foo(())); }
实际上,
void
就像一个
unit
类型,但只是半心半意的。为什么会这样


C++标准是否明确声明不能创建类型<代码>无效>代码>的值?如果是,这一决定背后的理由是什么?如果没有,为什么上面的代码没有编译

如果这是与向后兼容性相关的原因,请给出一个代码示例

明确地说,我不是在寻找解决问题的方法(例如,使用空的结构/类)。我想知道现状背后的历史原因

编辑:我稍微修改了代码示例中的语法,以明确我并没有试图劫持现有语法,如
voidfoo(void)
(因此,一些注释可能已经过时)。这个问题背后的主要动机是“为什么类型系统不像X”而不是“为什么这一点语法的行为不像我希望的那样”。如果你写的答案是关于向后兼容性的问题,请记住这一点。

< P>“C++标准明确地声明不能创建类型无效的值吗?”

对。它指出,
void
是一个不完整的类型,无法完成。不能创建类型不完整的对象或值

这是一条古老的规则;作为注释注释,它继承自C.,在C++中有一些小的扩展,以简化泛型代码的编写,例如:代码>空隙f-();void g(){return f();}合法


改变现状似乎没有什么好处。C++不是一种学术语言。纯洁不是目标。编写有用的程序是很困难的,但这样一个建议如何帮助做到这一点呢?引用Raymond Chen的话,每个提案都从-100开始,并且必须证明其添加的合理性;你不能为缺少功能辩护。

这确实是一个历史问题。用于区分返回值的函数和不返回值的子程序的旧(前C)语言(噢,Fortran IV和Basic的老味道…)。好吧,早期的C只允许函数,只是函数默认返回
int
,没有返回语句是合法的(意思是返回一个未指定的值),忽略任何返回值也是合法的,这样程序员就可以编写连贯的代码了。。。在早期,C或多或少被用作一个强大的宏汇编器,只要编译器能够将其翻译成机器指令(例如,没有严格的别名规则…),任何东西都是允许的。由于内存单元是
char
,不需要
void*
指针,
char*
就足够了

然后人们觉得有必要弄清楚,缓冲区应该包含任何内容,而不是字符串,有些函数永远不会返回值。而
void
感觉到了这种差距

缺点是,当您声明一个
void
函数时,您声明了一个被称为子例程的东西,这个东西永远不能用作值,特别是永远不能用作函数参数。因此,
void
不仅仅是一种无法实例化的特殊类型,它还声明结果不能是表达式的成员

由于语言继承,C标准库仍然是C++标准的一个子集,C++仍然处理<代码>空> <代码> ANSI C。


其他语言可以使用不同的约定。例如,在Python中,函数总是返回一些东西,如果没有遇到return语句,它只返回特殊的
None
值。生锈似乎还有另一个惯例。

有一个建议,你可能会觉得有趣。:)历史原因是,
void
及其几乎所有属性都直接来自C。问C为什么不从ML中获取特性是倒退的;C比ML大,所以我不确定你在问什么;为什么C++没有改变C的空隙?不会>代码> STD::单态< /代码>是ML模拟?(而不是解决方案)或者您希望C++改变“代码>空格”的语义,并打破向后兼容性,并大大阻碍C互操作性。(C互操作性已经有一系列的警告、陷阱和担忧。更改void的语义将是可怕的。)@Indigamer:另外,说“语句的类型是
void
”是不正确的。表达式有类型、语句,这些表达式可能没有<代码>虚空类型,而语句不是表达式,根本没有类型。@ IDEIAMER:仅仅因为一个学术人员给你描述了一个语言(席),其中的语句有类型,并不意味着C++是真的。在PDF中,我没有看到C++的声明。并不是所有的特性在变化和复杂性方面都有相同的成本(100位),并且不应该保持相同的标准。我可以想出两个例子:(1)我最近正试图编写一个eDSL,如果有一个
void
重载,那将是最符合人体工程学的;(2)添加一个合适的单元类型,为添加一个合适的无人居住类型铺平道路,它有自己的类型。另外,w.r.t.“C++不是一种学术语言,纯度不是一个目标。”。好吧,看看这让我们在语言复杂性方面做了什么?即使是解析它也是如此具有挑战性。没有消除小的不一致(
void
是唯一一种既不完整又无法完成的类型)使得理解类型sys变得困难