문제

In my code, I want to identify some properties about the contents of a file, before deciding how to read the file. (That is, I search for a keyword, if found, it's going to be read with foo(std::ifstream&), else with bar(std::ifstream&)).

I implemented the method that searches for the keyword as

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

This modifies the position of the file stream (either the end, if the keyword isn't found, or the position of the keyword). However I want that the position is reset after the search. This can be done with a 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);
      }
};

Now we add this to the method:

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

That's nice, because with exactly one additional line in the method, we get the behaviour of not modifying the std::ifstream no matter how the method is exited (one of the returns or an exception).

However, the method bool containsKeyword(std::ifstream&, const char*); does not express the constness. How can I adjust my method to express (at the level of the interface) that the method will not alter the current state?

도움이 되었습니까?

해결책

You could change the signature to take a position-guarded file:

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

This allows the caller to pass an ifstream per the current signature (constructing a temporary guard for that operation), or to make their own guard and use it for several operations.

You'll need to make the ifstream member publicly accessible.

다른 팁

Do it with the text comment // the method does read from file but resets the read pointer.

Do not expect a user of the API to be a monkey at keyboard. Specifically don't mark ifstream argument as const while casting constancy out inside the method. It does make difference in a multithreaded program.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top