为什么我不能对std :: ofstream

时间:2016-09-02 10:57:45

标签: c++ c++11 c++14 c++17

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

#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::fstream的{​​{1}}定义为operator bool(),但在这种情况下,我认为没有任何理由导致失败。没有中间转换,只有临时explicit对象和std::ofstream。是什么原因?

3 个答案:

答案 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>),因为隐式转换很危险。

相关问题