Reputation: 760
I'm just starting to learn C++ having come from a C# background.
I am creating a class that will parse CSV data, and I want the class to be initialized with either a filepath or a stream. If a filepath is passed the _str_in
should be set to a newly opened ifstream
.
My code below compiles but gives a warning on the second constructor "reference member is initialized to a temporary that doesn't persist after the constructor exits". I am guessing the warning relates to the following:
ifstream
is created and _str_in
is set to reference itifstream
is released after the constructor exits_str_in
now points to non-allocated memory and could become corrupted.I've tried different ways of accomplishing this and checked many SO questions but I'm stumped — any suggestions?
class TokenParser
{
std::istream& _str_in;
char _delim;
public:
TokenParser::TokenParser(std::istream& str_in, char delim) : _str_in(str_in), _delim(delim)
{
}
TokenParser::TokenParser(std::string& file_path, char delim) : _str_in(std::ifstream(file_path)), _delim(delim)
{
}
Upvotes: 2
Views: 1935
Reputation: 11028
Try this:
Using universal reference and std::move
in <algorithm>
class TokenParser
{
std::istream&& _str_in; // notice the && 'universal reference'
char _delim;
public:
TokenParser::TokenParser(std::istream&& str_in, char delim)
: _str_in(std::move(str_in)), _delim(delim)
{}
// other ctors...
}
Upvotes: 1
Reputation: 727077
The problem is pretty much what the compiler describes: the object created by std::ifstream(file_path)
will be gone by the time the constructor completes, so the reference _str_in
would instantly become dangling.
You could work around this problem by making an std::ifstream
object inside TokenParser
, and using it when the second constructor is called:
class TokenParser
{
std::ifstream _file;
std::istream& _str_in;
char _delim;
public:
TokenParser::TokenParser(std::istream& str_in, char delim) : _str_in(str_in), _delim(delim)
{
}
TokenParser::TokenParser(std::string& file_path, char delim) : _file(file_path), _str_in(_file)), _delim(delim)
{
}
...
}
Upvotes: 2