For this project, I do not have a lot ofaccess to Boost or C++11.
Note: I updated the question's description to clarify what I am doing. I have not changed the code wherethough, so no answer has been invalidated.
I needhave to format a stringdeal with functions that looks somethingreturn error codes.
When one of these functions fails in exceptional cases, I would like to construct an error message and throw a custom exception. Constructing an error message is rather cumbersome though because different functions in different contexts have varying information that would be useful to pass.
An example would be:
Let's say I'm trying to read data from an XML file and this is my interface:
void// FunctionIn (constheader file
struct FooData
{
std::string &strFile,strName const;
int n) std::vector <int> vecScores ;
{};
struct FooDataException : public std::stringruntime_error
{
s1 ;
FooDataException (const std::string s2&strWhat) : std::runtime_error (strWhat) {}
}
class FooDataLoader
{
public:
FooDataLoader () ;
~FooDataLoader () ;
//std::vector Do<FooData> stuffLoadFooData with(const s1std::string and&strPath) s2...
const ;
};
In my implementation file, I have two functions that help construct error messages to throw:
static void ThrowFunctionFailure (
ifconst (conditionstd::string ==&strWhere, false)
{ const std::string &strFunction,
const std::string &strMessage)
{
std::stringstream ss ;
ss << "Condition was"In false." "File:<< "strWhere <<
strFile << ", N = " << nstrFunction << ""failed. "
<< strMessage ;
Function2
(s1, s2, throw FooDataException (ss.str ()) ;
}
static void ThrowError (const }
std::string &strWhere, const std::string &strMessage)
{
// ...
}
The part I don't like is the:
std::stringstream ss ;
ss << "Condition was false."ss "File:<< "In " << strFilestrWhere << ", Nan =error occurred. " << nstrMessage <<;
" throw FooDataException (ss."str ()) ;
}
Now, these functions remove a lot of code duplication, but I would likestill have to do something likeconstruct an error message at the site:
void ReportErrorFooDataLoader::FooDataLoader ()
{
const stdHRESULT hr = ::stringCoInitialize strError(NULL) ;
// In some function if (FAILED (hr)) {
std::stringstream ss ;
int last_error = //.. ss << "HRESULT: " << hr << "." ;
ReportError ( throw ThrowFunctionFailure (std
"FooDataLoader::stringstreamFooDataLoader ()", <<
"Error Number "::CoInitialize ()",
<< last_error) ss.str ()
) ;
But that doesn't work for std::stringstream (at least it doesn't work on my compiler (Visual Studio 2008)).
Based on this answer, I wrote a quick and dirty workaround:
#include <string> }
#include}
FooDataLoader::~FooDataLoader <sstream>()
{
template <typename StringStreamT = ::CoUninitialize () ;
}
std::stringstream,vector typename<FooData> StringTFooDataLoader::LoadFooData =(const std::string>
classstring QuickStringStream&strPath) const
{
public:
typedefif StringStreamT(FileExist stringstream_type(strPath) ;== false) {
typedef StringT string_type std::stringstream ss ;
QuickStringStream () {}
ss << QuickStringStream"The (constfile, string_type" strData)<< {strPath << ", does not exist." ;
ss_ThrowError <<("FooDataLoader::LoadFooData strData()", ss.str ()) ;
}
template// <typenameSome T>xml library I have to use.
QuickStringStream&XmlReader operator<<xml ;
if (constxml.read T(strPath.data &tVal()) == -1) {
ss_ <<std::stringstream tValss ;
returnss *this<< "File: " << strPath << "." ;
}
ThrowFunctionFailure (
string_type str "FooDataLoader::LoadFooData ()", const
{ "XmlReader::read ()",
return ss_ ss.str ()
) ;
}
private:
stringstream_type// ss_More ;stuff...
};
Now, I canwould like to do stuffsomething like this:
#includeThrowFunctionFailure <iostream>
(
void println (std "FooDataLoader::stringLoadFooData &s()",
{ "XmlReader::read ()",
(std::coutstringstream () << s"File: " << "\n"strPath ;
}
int<< main".").str (void)
{) ;
But that doesn't work for std::stringstream (at least it doesn't work on my compiler (Visual Studio 2008)).
Based on this answer, I wrote a quick and dirty workaround:
#include <string>
#include <sstream>
template <typename StringStreamT = std::stringstringstream, stypename StringT = (std::string>
class QuickStringStream
{
public:
typedef StringStreamT stringstream_type QuickStringStream;
<> () << "Hello,typedef "StringT <<string_type 5;
<< " + "QuickStringStream <<() 5{}
<< " = "QuickStringStream <<(const 10string_type <<strData) "."{
).str () ;
ss_ << std::stringstrData strPath;
= "C:\\Stuff\\info.txt" ; }
println ((
template <typename T>
QuickStringStream& operator<< QuickStringStream(const <>T (&tVal) <<{
"The path " << strPath << " isss_ invalid.<< "tVal ;
).str ()) ;
return *this ;
println ((}
string_type str () const
QuickStringStream <> ("Error number:{
") << 53 << "."
return )ss_.str ()) ;
}
private:
returnstringstream_type 0ss_ ;
};
This does what I want, but I can't get rid of the feeling I have that this is a horrible idea.