how can I throw a string with some variables in it?

I have a function that does some logical error-checks on a structure I have, basically it will do a series of "if" checks and throw a string if it finds something wrong. This string is not caught, the idea is just to report the error and kill the process. I'd like to do something like this:

1
2
3
if (some_check) {
throw string("check(): Hidden node count of " + N_size_file + " exceeds maximum allowed value of " + _N_MAX);
}


I think you can see what I'm trying to do here. Obviously this doesn't work, but I would like this to basically throw this:

check(): Hidden node count of 5000 exceeds maximum allowed value of 4500


As I am writing dozens of these checks, I was hoping that I'd be able to keep it as short as possible. Performance is not an issue, as these checks are only performed during loading or in debugging situations.

Thanks in advance :)
Assume you are using Standard C++, please see http://www.cplusplus.com/reference/std/exception/exception/

All you got to do is inherit and override/implement according the base exception class listed.

class exception {
public:
exception () throw();
exception (const exception&) throw();
exception& operator= (const exception&) throw();
virtual ~exception() throw();
virtual const char* what() const throw();
}
Sample code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <fstream>
#include <exception>

using namespace std;

class MyException : public exception {
  private:
  string* m_ex;

  public:
  MyException(string& ex) {
    m_ex = new string(ex);
  };
  MyException(char* ex) {
    m_ex = new string(ex);
  };
  MyException(const MyException& e) throw() {
    if (e.m_ex) m_ex = new string(*(e.m_ex));
  }
  MyException& operator=(const MyException& e) throw() {
    if (e.m_ex) m_ex = new string(*(e.m_ex));
  }
  ~MyException() throw() {
    if (m_ex) delete m_ex;
  };
  const char* what() const throw() {
    return m_ex ? m_ex->c_str() : "cannot find exception string";
  }
};

int main(int argc,char** argv) {
  try {
    throw MyException("can see my exception?");
  } catch(MyException& ex) {
    cout << ex.what() << "\n";
  }
  return 0;
}
For dynamic parameter like N_size_file which is determined at run-time, you have two options. The C style using sprintf or C++ style using ostringstream.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <sstream>
#include <exception>

using namespace std;

class MyException : public exception {
  private:
  string* m_ex;

  public:
  MyException(const string& ex) {
    m_ex = new string(ex);
  };
  MyException(const char* ex) {
    m_ex = new string(ex);
  };
  MyException(const MyException& e) throw() {
    if (e.m_ex) m_ex = new string(*(e.m_ex));
  }
  MyException& operator=(const MyException& e) throw() {
    if (e.m_ex) m_ex = new string(*(e.m_ex));
  }
  ~MyException() throw() {
    if (m_ex) delete m_ex;
  };
  const char* what() const throw() {
    return m_ex ? m_ex->c_str() : "cannot find exception string";
  }
};

int main(int argc,char** argv) {
  int N = 10;
  try {
    #ifdef C_STYLE
    char buffer[81];
    sprintf(buffer,"C: can see my own exception %d?",N);
    throw MyException(buffer);
    #else
    ostringstream oss;
    oss << "C++: can see my own exception " << N << "?";
    throw MyException(oss.str());
    #endif

  } catch(MyException& ex) {
    cout << ex.what() << "\n";
  }
  return 0;
}


PS
1. Change parameter for constructor to const to reflect the intention of the class better.
2. C++ exception base class does not mandate a no-arg constructor so I did not code it. If you want you can add to the MyException class
Last edited on
I would write

throw std::runtime_error("check(): Hidden node count of " + std::to_string(N_size_file) + " exceeds maximum allowed value of " + std::to_string(_N_MAX));
demo: http://ideone.com/f5zln

or

throw std::runtime_error("check(): Hidden node count of " + boost::lexical_cast<std::string>(N_size_file) + " exceeds maximum allowed value of " + boost::lexical_cast<std::string>(_N_MAX));
demo: http://ideone.com/D13J9

or

throw std::runtime_error( str(boost::format("check(): Hidden node count of %d exceeds maximum allowed value of %d ") % N_size_file % N_MAX));
demo: http://ideone.com/D29fR
@sohguanh: ¿why are you using dynamic allocation?
¿what if it fails?
Yea, wouldnt it be best to check if he tpointers are NULL after allocating new strings in case the heap memory runs out? Thats another exception. lol
Last edited on
Hi I welcome all criticism. Going by argument, if heap memory can run out then so can stack memory. So does that mean if we switch to use stack memory we will be safe? Writing a bullet-proof exception class is not easy but I feel my version should suffice for most business needs unless it is very stringent memory environment. For that we should not even use exception class, we should revert back to use our traditional return int values isn't it ?
throw std::runtime_error("check(): Hidden node count of " + std::to_string(N_size_file) + " exceeds maximum allowed value of " + std::to_string(_N_MAX));


std::to_string(...) is there a standard C++ function called to_string ? Hmmm...
yes in C++11.
yes in C++11.


Thanks but it seems the Linux gcc compiler I have does not support C++11 yet so still need to use back stringstream class.
gcc 4.5 and newer has std::to_string if you activate C++11 by passing the flag -std=c++0x (or -std=c++11 in gcc 4.7) to gcc.
unless it is very stringent memory environment.
Maybe the trigger was a bad_alloc in the first place.
Still, the questions were unrelated. it was just a funny thought.

¿why do you unnecessary complicate your class by using dynamic allocation?
throw std::runtime_error("check(): Hidden node count of " + std::to_string(N_size_file) + " exceeds maximum allowed value of " + std::to_string(_N_MAX));

This is what I was after, thanks :)
why do you unnecessary complicate your class by using dynamic allocation?

Well it could be using stack also. Possibly since long time no touch C++ (busy with Android), I want to refresh my understanding of dynamic allocation :P

In a way, the example goes to show C++ is flexible to accommodate various mode unlike Java where all objects are stored by reference so as to speak.

If you like, you can just change the class to using stack variable also. It shouldn't be so hard, in fact it will be easier.

Topic archived. No new replies allowed.