Skip to main content
Code Review

Return to Question

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

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:

Replaced pseudo code with more concrete code, made question less ambiguous
Source Link
jliv902
  • 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.

edited body; edited tags
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

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)).

Source Link
jliv902
  • 2k
  • 16
  • 30
Loading
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /