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 或语句中的条件,这似乎是不切实际的.while
for
令人高兴的是,
N3290§4/ 3; 对于某些发明的临时变量(8.5),当且仅当声明格式正确时,
表达式e
才能隐式转换为类型.某些语言结构要求将表达式转换为布尔值.对于某些发明的临时变量(8.5),当且仅当声明格式正确时,表示出现在这样的上下文中的表达被上下文转换为并且格式良好.隐式转换的效果与执行声明和初始化相同,然后使用临时变量作为转换的结果.T
T t=e;
t
e
bool
bool t(e);
t
哪里bool t(e);
是直接初始化.
例如,您不必显式转换在a中用作条件的流对象while
,因为隐式地存在显式转换(他是).
不幸的是,搜索N3290我找不到任何"某些语言结构"的列表,但是在对这个答案的评论中,JohannesD写道:
通过FDIS搜索"上下文",整个列表似乎是:
if
,while
,do
,for
,noexcept
,和static_assert
条件; 第一个操作数?:
; 的两个操作数&&
和||
; 和.的操作数!
.
干杯&hth.,
归档时间: |
|
查看次数: |
920 次 |
最近记录: |