[英]Expressing “read-only, no modification of position” for std::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*);
不表达常数 。 如何调整我的方法以表示(在界面级别)该方法不会更改当前状态?
您可以更改签名以获取位置保护文件:
bool containsKeyword(const FilePositionScopeGuard &, const char *);
这使调用者可以根据当前签名传递ifstream
(为该操作构造一个临时保护),或者使自己成为保护程序并将其用于多个操作。
您需要使ifstream
成员可公开访问。
用文本注释进行// the method does read from file but resets the read pointer
。
不要期望API的用户会像键盘上的猴子。 具体来说,在方法内部强制转换常量时,请勿将ifstream
参数标记为const。 它确实在多线程程序中有所作为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.