为什么我不能编写以下代码?
#include <fstream>
#include <string>
bool touch(const std::string& file_path)
{
return std::ofstream(file_path, std::ios_base::app);
}
int main()
{
touch("foo.txt");
}
输出
prog.cpp: In function 'bool touch(const string&)':
prog.cpp:6:52: error: cannot convert 'std::ofstream {aka std::basic_ofstream<char>}' to 'bool' in return
return std::ofstream(file_path, std::ios_base::app);
我知道std::fstream
的{{1}}定义为operator bool()
,但在这种情况下,我认为没有任何理由导致失败。没有中间转换,只有临时explicit
对象和std::ofstream
。是什么原因?
答案 0 :(得分:13)
完全是因为 operator bool()
被定义为explicit
,您无法以这种方式使用它。自动调用explicit operator bool()
的唯一上下文是明确的条件,例如if
while
,?:
,!
以及{{1的中间表达式}}。 (有关更完整的摘要,请参阅我的问题When can I use explicit operator bool
without a cast?)。
for
语句的值永远不会从上下文转换为return
,因此如果您想将bool
转换为std::ofstream
作为返回值,你必须使用bool
或同等的。
答案 1 :(得分:3)
由于运算符被声明为显式,并且没有允许隐式转换为bool的上下文(例如在if语句中使用),因此您必须将带有流的表达式显式转换为bool
。
例如
bool touch(const std::string& file_path)
{
return bool( std::ofstream(file_path, std::ios_base::app) );
}
答案 2 :(得分:0)
operator bool
的定义如下:
explicit operator bool() {/*...*/}
注意在这里使用explicit,这意味着没有从类到bool的自动转换。这意味着对于您的代码,您必须这样做:
#include <fstream>
#include <string>
bool touch(const std::string& file_path)
{
return static_cast<bool>(std::ofstream(file_path, std::ios_base::app));
}
int main()
{
touch("foo.txt");
}
无论如何,都需要强制转换(最好是static_cast<bool>
),因为隐式转换很危险。