-2

This is the header file File.h:

#include "common.h"

#ifndef FILE_H
#define FILE_H
using namespace std;
class File : public fstream{
public:
        string file;
        File(){
                File("/tmp/text");
        }
        File(string file_name): file(file_name), fstream(file_name.c_str(), fstream::in | fstream::out){
        }
        void read_line();
};
#endif

And this is the File.cpp file:

#include "File.h"

void File::read_line(){
        string line;

        while(getline(*this, line)){
                cout << "line: " << line << endl;
        }
}

And following is the content of common.h

#include <iostream>
#include <stdlib.h>
#include <vector>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stack>
#include <unistd.h>
#include <cassert>
#include <stdexcept>
#include <getopt.h>
#include <fstream>
#include <istream>

When compiling above code, I get below error:

/home/rohit/cpp/cmake_projs/tree/src/File.cpp: In member function ‘void File::read_line()’:
/home/rohit/cpp/cmake_projs/tree/src/File.cpp:7:24: error: no matching function for call to ‘File::getline(File&, std::__cxx11::string&)’
  while(getline(*f, line)){
                        ^
In file included from /usr/include/c++/7/iostream:40:0,
                 from /home/rohit/cpp/cmake_projs/tree/include/common.h:1,
                 from /home/rohit/cpp/cmake_projs/tree/include/File.h:1,
                 from /home/rohit/cpp/cmake_projs/tree/src/File.cpp:1:

But the code compiles fine when I put almost same code in a different function not related to File class:

void test(){
        string line;
        File *f = new File("/tmp/abc");

        while(getline(*f, line)){
                cout << "line: " << line << endl;
        }
}

Why is this standard function hidden in the class function read_line() and not in an independent function?

Rohit
  • 604
  • 1
  • 10
  • 25
  • 5
    Ditch `using namespace std;` and qualify all `std` members. Not much typing really, and will save you a lot of grief. – StoryTeller - Unslander Monica Dec 24 '17 at 07:13
  • Thanks but why qualifying all `std` members solve the problem? – Rohit Dec 24 '17 at 07:21
  • 2
    Because unqualified name lookup in C++ is an intricate process. And adding namespace pollution into the mix makes it go bust. – StoryTeller - Unslander Monica Dec 24 '17 at 07:23
  • Thanks. But I wonder why my question was down-voted. Was my question incomplete, very easy to answer or less researched? I am a beginner and tried my level best to find the solution from the book by Bruce Eckel (that I have), here and there over the Internet. :) . And using the test() function approach was also a part of experiment. And I don't understand why namespace pollution busted test() approach. – Rohit Dec 24 '17 at 07:31
  • I wouldn't know. I didn't downvote it. – StoryTeller - Unslander Monica Dec 24 '17 at 07:32
  • Not a problem @StoryTeller :) Its just a question to general audience because I have experienced this like 2-3 times :) – Rohit Dec 24 '17 at 07:35
  • @Rohit Maybe because there is too much irrelevant code that distracts from the thing you want to find out. Posting a [mcve] always helps. – juanchopanza Dec 24 '17 at 07:35
  • Btw, if you are ever looking to refresh your book list, we have a curated list [available here](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – StoryTeller - Unslander Monica Dec 24 '17 at 07:39

2 Answers2

1

It is because fstream has a member getline that does not match, change the call to std::getline and it will work.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
1

It is a case of name lookup not working the way you expected.

Your class File inherits from fstream which inherits from istream. And istream has a member function getline, or two actually.

When you call an unqualified getline inside the class member, the compiler finds the inherited getline member and then doesn't look any further. In the free function test() there is no member function, so the compiler instead looks for the functions brought in by using namespace std;.

A solution is to explicitly use std::getline(*this, line) to show that you want to call a free function and not a member function.


This might also be yet another reason for not doing using namespace std;, but instead use std:: to refer to standard library names.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203