I'll be reviewing your implementation mainly, leaving the algorithm to another one.
using the whole namespace is generally considered a bad practice although in this small example there's very little chance of troubles.
LogFileName
need not be global: it's only used inmain
.Avoid global variables.
ToString<T>
is not needed: since C++11 there'sstd::to_string
, which also coversdouble
types.unit
may be initialized much better by using vectors initializer list:std::vector<std::string> units {elem1, elem2, elem3, ..., elemN};
You may avoid multiple
operator<<
calls with string literals by letting the preprocessor chain them together:outFile << "<!DOCTYPE html>\n" "<meta charset=\"UTF-8\">\n" "<html>\n" "<title>" << sourcePath.filename() << "</title>\n" "<body>\n";
In
main
you may want to check whethergetline
succeded.Log
need not beglobal
. See 2 & 3.
Error handling
Your error handling is awkward. Having a global object where you store possible errors and making the caller check for some is inefficient and, again, weird.
If you encounter an error, and your local code cannot do anything about that, either throw an exception (C++-style) or an error code with some related flag set accordingly (C-style). In the first case, you can decide to let the caller handle it (maybe adding some further information) until one of them is able to (or the program is exited) and keep throwing or locally, if you can.