I'm a bit confused on how to return an error with a complex data types, like my Vector of strings, would I just send a specific vector and let a simple if statement see if my return value was an error. Is there a more elegant solution?
This code belongs to a game I am working on, this is included in a class that reads a level from a .txt file and passes the map into a vector. I've edited the code a bit to take out the members.
std::vector<std::string> ReadMap(void) {
std::vector<std::string> VecMap;
std::string FileLine = "Level1.txt";
std::fstream _FileStream;
_FileStream.open(FileLine);
if (!_FileStream.is_open()) {
std::cout << "Something went wrong trying to open " << FileLine << "\nHave you included the file?" << std::endl;
return VecMap; // What should I do here?
}
while (std::getline(_FileStream, FileLine)) {
if (FileLine == "~") break;
else VecMap.push_back(FileLine);
}
_FileStream.close();
return VecMap;
}
You could, for example, pass in a reference to a variable as a parameter, and set the value of that parameter according to success or fail. The code would look like this:
1 2 3 4 5 6 7
bool error_happened;
return_value = ReadMap(error_happened);
if (error_happened)
{
// do something about the fact that it all went wrong
}
If you really need to return an error to the calling function you have a couple of options.
1. Throw an exception.
2. Instead of returning the vector, pass the vector to the function as a reference parameter.
3. Return an empty vector.
Also be aware that variable names beginning with an underscore is not recommended since in many cases the name may be reserved for the use of the implementation.
Certain sets of names and function signatures are always reserved to the implementation:
— Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.
— Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
Thanks for the reply, also note that this function is part of a class and _FileStream was a private member, I am a lazy copy and pasta!
This is the full, as yet unedited class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
class MapRead {
private:
std::fstream _FileStream;
std::string _FileName = "Level1.txt";
public:
MapRead() = default;
MapRead(const std::string FileNameArg) : _FileName(FileNameArg) { }
// Read in Map from file and pass vector to main
std::vector<std::string> ReadMap(void);
std::vector<std::string> ReadMap(const std::string FileNameArg);
// Read in scripts from file to pass to main
std::vector<ObjectDetect> ReadScript(void);
std::vector<ObjectDetect> ReadScript(const std::string FileNameArg);
};
If it's part of a class, you could have a class boolean member errorStatus and a class string lastError. When something bad happens, set errorStatus to true and put a meaningful string in lastError for the user to dump to a log file or put on screen or some other such useful feedback mechanism.
This does rely on the user checking the errorStatus, but so long as a class is well documented, that's up to them.