c++ - 为 std::ifstream 表达 "read-only, no modification of position"

标签 c++ c++11 constants fstream ifstream

在我的代码中,我想在决定如何读取文件之前识别文件内容的一些属性。 (也就是说,我搜索一个关键字,如果找到,它将用 foo(std::ifstream&) 读取,否则用 bar(std::ifstream&) ).

我实现了搜索关键字的方法为

bool containsKeyword(std::ifstream& file, const char* keyword)
{
    for ( std::string line; std::getline(file, line); )
    {
        if ( line == keyword )
        {
            return true;
        }
    }
    return false;
}

这会修改文件流的位置(如果没有找到关键字,则为结尾,或者关键字的位置)。但是我希望在搜索后重置位置。这可以通过 ScopeGuard 完成:

class FilePositionScopeGuard
{
   private:
      std::ifstream& file;
      using FilePosition = decltype(std::declval<std::ifstream>().tellg());
      FilePosition initial_position;
   public:
      FilePositionScopeGuard(std::ifstream& file_)
      :
         file(file_),
         initial_position(file.tellg())
      {
      }
      ~FilePositionScopeGuard()
      {
         file.clear();
         file.seekg(initial_position);
      }
};

现在我们将其添加到方法中:

bool containsKeyword(std::ifstream& file, const char* keyword)
{
    FilePositionScopeGuard guard(file);
    for ( std::string line; std::getline(file, line); )
    {
        ...

这很好,因为在方法中只增加了一行,我们得到了不修改 std::ifstream 的行为,无论方法如何退出(返回或异常之一) ).

但是,方法bool containsKeyword(std::ifstream&, const char*); 没有表达constness。我如何调整我的方法以表达(在界面级别)该方法不会改变当前状态?

最佳答案

您可以更改签名以采用位置保护文件:

bool containsKeyword(const FilePositionScopeGuard &, const char *);

这允许调用者根据当前签名传递一个 ifstream(为该操作构建一个临时守卫),或者创建他们自己的守卫并将其用于多个操作。

您需要使 ifstream 成员可公开访问。

关于c++ - 为 std::ifstream 表达 "read-only, no modification of position",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21456438/

相关文章:

perl - "Recursive"perl 中的常量

c++ - 将 const 指针 (EVP_MD) 保存到变量,以便在类方法 (HMAC) 中重新使用它

c++ - C 将一个数分解为质因数

c++ - 增加 void 指针不能正确设置值

c++ - 为什么 std::is_const<const int&>::value 评估为 false?

c++ - 为什么非常量引用参数可以绑定(bind)到临时对象?

c++ - 如何使用 X11 避免图形绘图中的闪烁

c++ - 如何从 OpenCV C++ 中的图像中裁剪特定的矩形部分(ROI)

c++ - 移动构造函数应该采用 const 还是非 const 右值引用?

c++ - 将 std::vector<std::shared_ptr<T>> 转换为 std::vector<std::shared_ptr<const T>>