为什么我不能在std::ofstream中使用operator bool()运算符?

7

为什么我不能编写以下代码?

#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::fstreamoperator bool() 被定义为 explicit,但我不清楚它在这种情况下为什么会失败。没有中间转换,只有临时的 std::ofstream 对象和 bool。是什么原因呢?

http://ideone.com/IhaRaD


1
由于操作符是显式的,且没有上下文可以隐式地转换为bool,因此您必须显式地将其转换为bool。 :) - Vlad from Moscow
显式转换使其不会转换为布尔值,除非您直接调用强制转换。 - Tomasz Plaskota
2
这里可以使用 return !! - Johannes Schaub - litb
3个回答

13

正是因为 operator bool() 被定义为 explicit,所以你不能以这种方式使用它。唯一自动调用 explicit operator bool() 的上下文是明确的条件语句,例如 if, while, ?:, !for 中的中间表达式。(更完整的总结,请参见我的问题When can I use explicit operator bool without a cast?)。

return 语句的值永远不会被上下文转换为 bool,所以如果你想将 std::ofstream 转换为 bool 作为返回值,你必须使用 static_cast<bool>() 或等价物。


3

由于操作符被声明为显式且没有上下文允许隐式转换为bool(例如在if语句中使用),因此您必须显式地使用流将表达式转换为bool。 例如:

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

0

operator bool的定义如下:

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

请注意这里使用了 explicit,这意味着没有从类到布尔值的自动转换。这意味着对于您的代码,您必须执行以下操作:
#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>),因为隐式类型转换是危险的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接