[英]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.