Based on this answer this answer, I wrote a quick and dirty workaround:
Based on this answer, I wrote a quick and dirty workaround:
Based on this answer, I wrote a quick and dirty workaround:
- 2k
- 16
- 30
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.
I have a lot of code where I need to format a string that looks something like this:
void Function (const std::string &strFile, const int n)
{
std::string s1 ;
std::string s2 ;
// Do stuff with s1 and s2...
if (condition == false) {
std::stringstream ss ;
ss << "Condition was false." "File: " << strFile << ", N = " << n << "." ;
Function2 (s1, s2, ss.str ()) ;
}
// ...
}
The part I don't like is the:
std::stringstream ss ;
ss << "Condition was false." "File: " << strFile << ", N = " << n << "." ;
I would like to do something like:
void ReportError (const std::string strError) ;
// In some function:
int last_error = //...
ReportError ((std::stringstream () << "Error Number: " << last_error).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 <sstream>
template <typename StringStreamT = std::stringstream, typename StringT = std::string>
class QuickStringStream
{
public:
typedef StringStreamT stringstream_type ;
typedef StringT string_type ;
QuickStringStream () {}
QuickStringStream (const string_type strData) {
ss_ << strData ;
}
template <typename T>
QuickStringStream& operator<< (const T &tVal) {
ss_ << tVal ;
return *this ;
}
string_type str () const
{
return ss_.str () ;
}
private:
stringstream_type ss_ ;
};
Now, I can do stuff like this:
#include <iostream>
void println (std::string &s)
{
std::cout << s << "\n" ;
}
int main (void)
{
std::string s = (
QuickStringStream <> () << "Hello, " << 5 << " + " << 5 << " = " << 10 << "."
).str () ;
std::string strPath = "C:\\Stuff\\info.txt" ;
println ((
QuickStringStream <> () << "The path " << strPath << " is invalid. "
).str ()) ;
println ((
QuickStringStream <> ("Error number: ") << 53 << "."
).str ()) ;
return 0 ;
}
This does what I want, but I can't get rid of the feeling I have that this is a horrible idea.
For this project, I do not have access to Boost or C++11.
Note: I updated the question's description to clarify what I am doing. I have not changed the code though, so no answer has been invalidated.
I have to deal with functions that return 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:
// In header file
struct FooData
{
std::string strName ;
std::vector <int> vecScores ;
};
struct FooDataException : public std::runtime_error
{
FooDataException (const std::string &strWhat) : std::runtime_error (strWhat) {}
}
class FooDataLoader
{
public:
FooDataLoader () ;
~FooDataLoader () ;
std::vector <FooData> LoadFooData (const std::string &strPath) const ;
};
In my implementation file, I have two functions that help construct error messages to throw:
static void ThrowFunctionFailure (
const std::string &strWhere, const std::string &strFunction,
const std::string &strMessage)
{
std::stringstream ss ;
ss << "In " << strWhere << ", " << strFunction << "failed." << strMessage ;
throw FooDataException (ss.str ()) ;
}
static void ThrowError (const std::string &strWhere, const std::string &strMessage)
{
std::stringstream ss ;
ss << "In " << strWhere << ", an error occurred. " << strMessage ;
throw FooDataException (ss.str ()) ;
}
Now, these functions remove a lot of code duplication, but I still have to construct an error message at the site:
FooDataLoader::FooDataLoader ()
{
const HRESULT hr = ::CoInitialize (NULL) ;
if (FAILED (hr)) {
std::stringstream ss ;
ss << "HRESULT: " << hr << "." ;
throw ThrowFunctionFailure (
"FooDataLoader::FooDataLoader ()", "::CoInitialize ()",
ss.str ()) ;
}
}
FooDataLoader::~FooDataLoader ()
{
::CoUninitialize () ;
}
std::vector <FooData> FooDataLoader::LoadFooData (const std::string &strPath) const
{
if (FileExist (strPath) == false) {
std::stringstream ss ;
ss << "The file, " << strPath << ", does not exist." ;
ThrowError ("FooDataLoader::LoadFooData ()", ss.str ()) ;
}
// Some xml library I have to use.
XmlReader xml ;
if (xml.read (strPath.data ()) == -1) {
std::stringstream ss ;
ss << "File: " << strPath << "." ;
ThrowFunctionFailure (
"FooDataLoader::LoadFooData ()",
"XmlReader::read ()",
ss.str () ) ;
}
// More stuff...
}
I would like to do something like:
ThrowFunctionFailure (
"FooDataLoader::LoadFooData ()",
"XmlReader::read ()",
(std::stringstream () << "File: " << strPath << ".").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 <sstream>
template <typename StringStreamT = std::stringstream, typename StringT = std::string>
class QuickStringStream
{
public:
typedef StringStreamT stringstream_type ;
typedef StringT string_type ;
QuickStringStream () {}
QuickStringStream (const string_type strData) {
ss_ << strData ;
}
template <typename T>
QuickStringStream& operator<< (const T &tVal) {
ss_ << tVal ;
return *this ;
}
string_type str () const
{
return ss_.str () ;
}
private:
stringstream_type ss_ ;
};
This does what I want, but I can't get rid of the feeling that this is a horrible idea.
But that doesn't work for std::stringstream
(at least it doesn't work on my compiler (visual studioVisual Studio 2008)).
But that doesn't work for std::stringstream
(at least it doesn't work on my compiler (visual studio 2008)).
But that doesn't work for std::stringstream
(at least it doesn't work on my compiler (Visual Studio 2008)).