0
votes

How am I supposed to do something like this in C++?

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

string input_filename_ = "";

istream& input = (input_filename_ == "") ? cin : ifstream(input_filename_, ifstream::in);

I am getting this error and don't know why.

E0330 "std::basic_istream<_Elem, _Traits>::basic_istream(std::basic_istream<_Elem, _Traits>::_Myt &&_Right) [with _Elem=char, _Traits=std::char_traits]" (declared at line 55 of "d:\Program Files\Visual Studio 2017\VC\Tools\MSVC\14.11.25503\include\istream") is inaccessible

2
You need to include fstream and sstream - Jake Freeman
fstream is already included and I don't need sstream, do I? - Speedding
lvalue reference cannot bind to temporary. - Incomputable
@speeding I believe so. - Jake Freeman

2 Answers

1
votes

When you use

istream& input = (input_filename_ == "") ? cin : ifstream(input_filename_, ifstream::in);

The last part of the expression is a temporary. You can't use it to initialize a non-const reference.

You'll have to deal with it slightly differentely.

std::ifstream str;
std::istream* str_ptr = &std::cin;
if (input_filename_ != "")
{
   str.open(input_filename_);
   str_ptr = &str;
}

std::istream& input = *str_ptr;
1
votes

You can't bind a temporary to your non-const reference. You have to create a real variable and bind that:

ifstream ifs(input_filename, ifstream::in); // a real variable
istream& input = input_filename.empty() ? cin : ifs; // that should bind properly

Usually I do something more similar to this to make sure the user supplied a file name and the file opened properly:

std::ifstream ifs;

if(!file_name.empty()) // do we have a file name?
    ifs.open(file_name); // try to open it

if(!ifs) // if we tried to open it but it failed
    throw std::runtime_error(std::string(std::strerror(errno)) + ": " + file_name);

// only attach file to reference if user gave a file name
std::istream& in = file_name.empty() ? std::cin : ifs;