IgorLopez IgorLopez - 3 months ago 18
C++ Question

C++, passing filename in string to class function using it for ifstream object

I am a C++ newbie and do not understand why my very simple code does not compile. I am trying to instantiate an ifstream object in my class by passing in a string from first argument to the app.

Building gives: error: no match for call to '(std::ifstream) (const char*)'

Header:


#ifndef _SIMPLE_TEST
#define _SIMPLE_TEST

#include <iostream>
#include <fstream>
#include <string.h>

class mytest {
public:
mytest(int number);
bool validate_config(const std::string &s);
private:
std::ifstream configFileStream;
int magic;
};

#endif


Code:


#include <iostream>
#include <fstream>
#include <string.h>
#include "simple.hpp"


mytest::mytest(int number) {
magic = number;
}

bool mytest::validate_config(const std::string &s) {
configFileStream(s.c_str());
return true;
}

int main(int argc, char **argv) {
bool check;
std::string configFile(argv[1]);
mytest DBG(17);
check = DBG.validate_config(configFile.c_str());
if (check) {
return 0;
}
return -1;
}


Build error (from console):


Compile src/simple.cpp
src/simple.cpp: In member function 'bool mytest::validate_config(std::string)':
src/simple.cpp:12:28: error: no match for call to '(std::ifstream) (const char*)'
Makefile:23: recipe for target `_out/simple.o' failed
make: *** [_out/simple.o] Error 1


I have searched and the outcome has always bee that it should work since
I am passing the output from string class c_str() method to the mytest validate_config method (sorry for bad format of the console output)

Answer

The syntax you're using inside mytest::validate_config is not doing what you expect.

configFileStream(s.c_str());
// tries to call 
// `std::ifstream::operator()(const char*)`
// which does not exist

Check out ifstream on cppreference to verify that there's no call operator.


If you want to replace the existing ifstream instance with a new one, you have to call its constructor:

configFileStream = std::ifstream(s.c_str());
// creates a temporary `ifstream` from `s.c_str()`
// and assigns it to `configFileStream`

The above line of code is calling ifstream::ifstream constructor (2) and then ifstream::operator=.

Assigning a temporary ifstream to an existing one is only supported since C++11.


A more straightforward way of achieving what you desire is using the ifstream::open method:

configFileStream.open(s.c_str());

This approach does not create any temporary object.

Comments