为什么我不能对 std::ofstream 使用 operator bool()

Why can't I use operator bool() for std::ofstream

为什么我不能写下面的代码?

#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);

http://ideone.com/IhaRaD

我知道 std::fstreamoperator bool() 定义为 explicit,但我看不出在这种情况下它会失败的任何原因。没有中间转换,只有临时 std::ofstream 对象和 bool。什么原因?

正是因为operator bool()定义为explicit所以不能这样使用。自动调用 explicit operator bool() 的唯一上下文是明确的条件,例如 if while?:! 和 [=17 的中间表达式=]. (有关更完整的摘要,请参阅我的问题 When can I use explicit operator bool without a cast?)。

return 语句的值永远不会 根据上下文转换为 bool,因此如果您想将 std::ofstream 转换为 bool 作为 return 值,您 必须 使用 static_cast<bool>() 或等效值。

由于运算符声明为显式,并且没有上下文允许隐式转换为布尔值(例如在 if 语句中使用),因此您必须将表达式与流显式转换为 bool . 例如

bool touch(const std::string& file_path)
{
    return bool( std::ofstream(file_path, std::ios_base::app) );
}

operator bool 的定义如下所示:

explicit operator bool() {/*...*/}

注意这里使用了 explicit,这意味着没有从 class 到 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>),因为隐式转换很危险。