Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

Based on this answerthis 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