C++ 删除cout;删除cin;不要给出编译错误-标准库中的一个缺陷?

C++ 删除cout;删除cin;不要给出编译错误-标准库中的一个缺陷?,c++,stream,c++11,implicit-conversion,C++,Stream,C++11,Implicit Conversion,以下内容是否会给出编译错误 delete cout; delete cin; 答案是:没有 这是标准库中流类实现中的一个缺陷。它们具有以下类型转换函数,这意味着所有流对象都可以隐式转换为void*: operator void * ( ) const; 这在一般情况下非常有用,因为它允许我们在读取文件输入时进行写入。但同时,它允许用户编写删除流。正如我所说,您可以删除任何流对象。因此,所有这些都是允许的: delete ss; //declare std::stringstream ss;

以下内容是否会给出编译错误

delete cout;
delete cin;
答案是:没有

这是标准库中流类实现中的一个缺陷。它们具有以下类型转换函数,这意味着所有流对象都可以隐式转换为
void*

operator void * ( ) const;
这在一般情况下非常有用,因为它允许我们在读取文件输入时进行写入。但同时,它允许用户编写
删除流
。正如我所说,您可以删除任何流对象。因此,所有这些都是允许的:

delete ss;  //declare std::stringstream ss;
delete iss; //declare std::istringstream iss;
delete oss; //declare std::ostringstream oss;
只是他们会发出警告,说(见):

警告:删除“void*”未定义

您只需将其强制转换为
char*
。但该程序仍然存在问题,运行时很可能会崩溃

--

所以我的问题是,这个问题在C++11中得到解决和修复了吗?以下文章提供了一个解决此问题的方法:

--

编辑:

根据@Xeo对@Alf答案的评论:

提出解决此问题的文件:


它显然已经修复

至少,在N3290中,您有
std::basic_ios::operator bool
而不是
void*
转换,并且该
operator bool
声明为
显式

请注意,C++98/C++03不支持显式类型转换运算符,但C++11支持

显式
类型转换运算符

N3290§12.3.2/2
仅被视为用户定义的转换 用于直接初始化(8.5)

这对于
while
for
语句中的条件似乎是不切实际的

幸好

N3290§4/3
表达式
e
可以隐式转换为类型
T
,当且仅当声明
T=et
(8.5),code>格式良好。某些语言构造要求将表达式转换为布尔值。 在这样的上下文中出现的表达式
e
被称为上下文转换为
bool
,并且当且仅当声明
bool t(e)时,该表达式是格式良好的t
(8.5),code>格式良好。任一隐式转换的效果都与执行 声明和初始化,然后使用临时变量作为转换的结果

其中
bool t(e)是直接初始化

例如,您不必显式转换
中用作条件的流对象,而
,因为存在显式转换(he-he)

不幸的是,搜索N3290时,我找不到发生这种情况的任何“特定语言结构”列表,但JohannesD在对此答案的评论中写道:


在FDI中搜索“上下文”,整个列表似乎是:
如果
执行
用于
无异常
,以及
静态断言
条件;
的第一个操作数:
;二者都
&&
|
的操作数;和
的操作数


干杯&hth.,

如果我能拿出我的2美分,我认为标准库有点“缺陷”,尽管用意很好

引入了
操作符void*()
,以允许类似
while(stream)
if(!stream)
while(stream&…
),而不提供对整数算术的隐式访问(该
运算符bool
将提供)。 事实上,这将禁用整数运算,但允许访问指针功能(如删除…)

现在,在C++0x中,引入了一个显式的oeprator bool()
。它不会隐式地提供对任何特性的访问,因为它需要隐式转换。但是稍等一下:“while(bool(stream))”甚至
while(static_cast(stream))
都太罗嗦了。。。 操作人员是明确的,并且 “while(!!stream)”看起来非常有效,我甚至想知道为什么不接受它作为范例:

如果我想将某些东西显式转换为bool,我只需要提供一个
操作符!()
成员“无效”和
为“有效”


比隐式转换安全得多,而且不会毫无意义地罗嗦:毕竟
永远存在

c++为你提供了很多方法来击打你自己的脚。这是其中之一;)我想说这是直截了当的射击!:-)幸运的是,有一个简单的变通方法可以用“Well don't do than”的语言来解决:)@Nawaz:Safe Bool成语是在C++98发布后发明的(我不知道C++03的用法),所以这很正常。请注意,尽管他们已经考虑过这个问题,但因为他们使用了
void*
(在大多数上下文中都会发出警告),而不是直接使用
char*
bool
。您不应该更担心没有任何警告。是的,这就是愚蠢的C++11“隐式显式”。他——)它也被固定在核心语言方面。
delete
操作符现在只考虑将函数转换为指向对象类型的指针。因此,这种情况不再具有未定义的行为,而是需要进行诊断。当然,这不需要对他的实现进行正式的更改(他已经得到了诊断),但很可能实现现在将拒绝,而不仅仅是警告……这是标准转换i第4条的一部分:“确定”