删除cout;删除cin不提供编译错误 - 标准库中的缺陷? [英] delete cout; delete cin; do not give compilation error - a flaw in the Standard library?

查看:113
本文介绍了删除cout;删除cin不提供编译错误 - 标准库中的缺陷?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是否会产生编译错误?

  delete cout; 
delete cin;

答案是:



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

  operator void *()const; 

这在一般情况下非常有用,因为它允许我们写非常惯用的循环,例如,当从文件读取输入时。但同时,它允许用户写 delete stream 。正如我所说,你可以删除任何流对象。所有这些都是允许的:

  delete ss; // declare std :: stringstream ss; 
delete iss; // declare std :: istringstream iss;
delete oss; // declare std :: ostringstream oss;

只是他们会给出警告,说: ideone ):


警告:删除void *未定义


,您可以轻松避免,只需投射,即 char *



-



因此,我的程序可能会在运行时崩溃。问题是,这个问题是否已经解决和修复,在C ++ 11?以下文章为此问题提供了一个修正:





-



编辑:



From @ Xeo对@ Alf的回答的评论:





提出此问题修复的论文:




解决方案



至少在N3290中有 std :: basic_ios :: operator bool void * 转换,并且此运算符bool 被声明为 explicit 显式 c>类型转换运算符



显式类型转换运算符


N3290§12.3.2/ 2;

只被视为用户定义的转换
用于直接初始化(8.5)


这可能看起来不太实用在例如a while for 语句。



/ p>


N3290§4/ 3;

表达式如果且仅当声明 T t = 时, c 可以隐式转换对于一些发明的临时变量 t (8.5),e 是合格的。某些语言结构要求将表达式转换为布尔值。
在这种上下文中出现的表达式 e 被称为上下文转换为 bool / em>,并且当且仅当声明 bool t(e); 形式良好时,对于一些发明的临时变量 t (8.5)。隐式转换的效果与执行
声明和初始化相同,然后使用临时变量作为转换结果。


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



例如你不必显式转换一个用作中的条件的流对象,而,因为隐式显式转换(他)。



不幸的是,搜索N3290我可以找到任何列表的某些语言结构在这种情况下,但在对此回答的评论中JohannesD写道:


通过FDIS搜索上下文为 if while
do 代表 c $ c> noexcept
static_assert 条件; ?: 的第一个操作数; && ||
操作数
;和 的操作数。


& hth。,


Will the following give a compilation error?

delete cout;
delete cin;

The answer is : No.

It is a flaw in the implementation of stream classes from the Standard library. They have the following conversion function to void* type, which means, all stream objects can be implicitly converted to void*:

operator void * ( ) const;

This is very useful in general as it lets us write very idiomatic loop, say, when reading input from files. But at the same time, it lets user to write delete stream. As I said, you can delete any stream object. So all of these are allowed:

delete ss;  //declare std::stringstream ss;
delete iss; //declare std::istringstream iss;
delete oss; //declare std::ostringstream oss;

Only that they'll give a warning, saying (see at ideone):

warning: deleting ‘void*’ is undefined

which you can easily avoid just by casting, say, tochar*. But the program has still issue, and most likely will crash when running it.

--

So my question is, has this issue been addressed and fixed, in C++11? The following article provides one fix for this problem:

--

Edit:

From @Xeo's comment on @Alf's answer:

The paper which proposed a fix for this issue:

解决方案

It has apparently been fixed.

At least, in N3290 you have std::basic_ios::operator bool instead of that void* conversion, and this operator bool is declared explicit.

Note that C++98/C++03 did not support explicit type conversion operators, but C++11 does.

An explicit type conversion operator

N3290 §12.3.2/2;
is only considered as a user-defined conversion for direct-initialization (8.5)

And that might seem to be impractical for the condition in e.g. a while or for statement.

Happily,

N3290 §4/3;
An expression e can be implicitly converted to a type T if and only if the declaration T t=e; is well-formed, for some invented temporary variable t (8.5). Certain language constructs require that an expression be converted to a Boolean value. An expression e appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the declaration bool t(e); is well-formed, for some invented temporary variable t (8.5). The effect of either implicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion.

where bool t(e); is a direct-initialization.

E.g. you don’t have to explicit convert a stream object used as condition in a while, because there is implicitly an explicit conversion (he he).

Unfortunately, searching N3290 I can’t find any list of the “certain language constructs” where this happens, but in comments to this answer JohannesD wrote:

Searched through the FDIS for “contextually”, and the whole list seems to be: if, while, do, for, noexcept, and static_assert conditions; the first operand of ?:; both operands of && and ||; and the operand of !.

Cheers & hth.,

这篇关于删除cout;删除cin不提供编译错误 - 标准库中的缺陷?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆