Naw*_*waz 14 c++ stream implicit-conversion c++11
以下是否会出现编译错误?
delete cout;
delete cin;
Run Code Online (Sandbox Code Playgroud)
答案是不.
它是标准库中流类实现的一个缺陷.它们具有以下要转换的转换函数void*,这意味着,所有流对象都可以隐式转换为void*:
operator void * ( ) const;
Run Code Online (Sandbox Code Playgroud)
这一般非常有用,因为它可以让我们在从文件读取输入时编写非常惯用的循环.但与此同时,它让用户可以写delete stream.正如我所说,您可以删除任何流对象.所以这些都是允许的:
delete ss; //declare std::stringstream ss;
delete iss; //declare std::istringstream iss;
delete oss; //declare std::ostringstream oss;
Run Code Online (Sandbox Code Playgroud)
只有他们会发出警告,说(见ideone):
警告:删除'void*'未定义
你可以轻易地通过铸造来避免,比如说char*.但该程序仍然存在问题,并且在运行时很可能会崩溃.
-
所以我的问题是,在C++ 11中这个问题已得到解决和修复吗?以下文章提供了此问题的一个修复:
-
编辑:
来自@ Xeo对@ Alf答案的评论:
提出修复此问题的论文:
Che*_*Alf 18
它显然是固定的.
至少,在N3290中你有std::basic_ios::operator bool而不是那个void*转换,并且这operator bool是声明的explicit.
请注意,C++ 98/C++ 03不支持explicit类型转换运算符,但C++ 11 支持类型转换运算符.
一个explicit类型转换操作符
N3290§12.3.2/ 2;
仅被视为用户定义的直接初始化转换(8.5)
对于例如a 或语句中的条件,这似乎是不切实际的.whilefor
令人高兴的是,
N3290§4/ 3; 对于某些发明的临时变量(8.5),当且仅当声明格式正确时,
表达式e才能隐式转换为类型.某些语言结构要求将表达式转换为布尔值.对于某些发明的临时变量(8.5),当且仅当声明格式正确时,表示出现在这样的上下文中的表达被上下文转换为并且格式良好.隐式转换的效果与执行声明和初始化相同,然后使用临时变量作为转换的结果.TT t=e;teboolbool t(e);t
哪里bool t(e);是直接初始化.
例如,您不必显式转换在a中用作条件的流对象while,因为隐式地存在显式转换(他是).
不幸的是,搜索N3290我找不到任何"某些语言结构"的列表,但是在对这个答案的评论中,JohannesD写道:
通过FDIS搜索"上下文",整个列表似乎是:
if,while,do,for,noexcept,和static_assert条件; 第一个操作数?:; 的两个操作数&&和||; 和.的操作数!.
干杯&hth.,