Sign in to follow this  
Enerjak

Little help with throwing exceptions (custom ones).

Recommended Posts

Ok, now, I had a generic class called IrrOrderedLinkedList<T> ok? now, if i make it a string list, nothing happens and it works fine
BUT when I make it an int, i get an error because of these two lines:

[CODE]
string s = " ";
s += "Item " + current->data + " is not in the list.";
throw s;
throw "The item " + current->data + " is not in the list";
[/CODE]

not sure how to solve this problem, hopefully, someone in the audience can help out.

Share this post


Link to post
Share on other sites
You need to convert the int (current->data) to string.
This is C++, you can't just join an integer to a std::string.

[CODE]
char buffer[128];
sprintf(buffer, "%d", current->data);
s += "Item " + buffer + " is not in the list.";
[/CODE]

Share this post


Link to post
Share on other sites
[quote name='wqking' timestamp='1333509514' post='4928085']
This is C++, you can't just join an integer to a std::string.
[CODE]char buffer[128];
sprintf(buffer, "%d", current->data);
s += "Item " + buffer + " is not in the list.";[/CODE][/quote]
That is fairly efficient (although error checking would be nice), but a complete hassle if you want to expand it to other types beyond just integers.

In C++, we have stringstreams for this purpose:
[code]std::ostringstream os;
os << current->data;
s += os.str();[/code]

Or, if you have access to Boost, see [url="http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast.html"]lexical_cast[/url].

Share this post


Link to post
Share on other sites
You should be thowing exception objects, not strings. The standard exception classes can store strings:
[code]
#include <stdexcept>

if ( /* not found */ )
{
std::stringstream message;
message << "Item " << current->data << " is not in the list.";
throw std::runtime_error(message.str());
}
[/code]
I'm not sure that failing to find an element in a list is even an exceptional case (depending on the nature of the function). Returning a boolean value, or otherwise avoiding exceptions, might be a better design. Note for instance that there are relatively few cases in the C++ standard library where exceptions are thrown (allocation failures aside).

Share this post


Link to post
Share on other sites
The problem is that current->data’s type matches the T template parameter.

Resolve the types:

[color=#008800]"Item "[/color][color=#000000] [/color][color=#666600]+[/color][color=#000000] current[/color][color=#666600]->[/color][color=#000000]data [/color][color=#666600]+[/color][color=#000000] [/color][color=#008800]" is not in the list."[/color][color=#666600];[/color]
=

[color=#008800]"Item "[/color][color=#000000] [/color][color=#666600]+[/color][color=#000000] std::string[/color][color=#000000] [/color][color=#666600]+[/color][color=#000000] [/color][color=#008800]" is not in the list."[/color][color=#666600];[/color]

And once you used an int for the T value, it became:

[color=#008800]"Item "[/color][color=#000000] [/color][color=#666600]+[/color][color=#000000] int[/color][color=#000000] [/color][color=#666600]+[/color][color=#000000] [/color][color=#008800]" is not in the list."[/color][color=#666600];[/color]

There is no operator for the int-to-std::string conversion in the std::string class.

Using << as suggested by rip-off will fix this issue, and following the rest of his advice won’t hurt.


L. Spiro

Share this post


Link to post
Share on other sites
Worse still, if you had written "Item is not found in list: " + current->data, it would be interpreted as pointer arithmetic, and could result in undefined behaviour depending on the value of current->data.

Share this post


Link to post
Share on other sites
If you are referring to my latest post, the answer is that the string literal is an array of characters, which decays to a pointer. Adding an integer to a pointer is pointer arithmetic, which advances the pointer N elements, where N is current->data. This is all legal, just unintended. It becomes illegal if the value of current->data is negative, or exceeds the length of the string.

While it is legal to take a pointer to the "one past the end" of this array (which in this case would point just after the implied NUL character in the string literal) the chances are that whatever is done next with this pointer will be illegal. Passing it to a C style string API, such as operator<<(std::ostream &, const char *) is not allowed.

Share this post


Link to post
Share on other sites
[quote name='swiftcoder' timestamp='1333512840' post='4928093'] [quote name='wqking' timestamp='1333509514' post='4928085'] This is C++, you can't just join an integer to a std::string. [CODE]char buffer[128]; sprintf(buffer, "%d", current->data); s += "Item " + buffer + " is not in the list.";[/CODE][/quote] That is fairly efficient (although error checking would be nice), but a complete hassle if you want to expand it to other types beyond just integers. In C++, we have stringstreams for this purpose: [code]std::ostringstream os; os << current->data; s += os.str();[/code] Or, if you have access to Boost, see [url="http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast.html"]lexical_cast[/url]. [/quote]

I tried to download Boost, but when i compiled it with the exe it made libs for vsc++ 2010. I don't know how to make it be for 2008, any ideas? I wanna use this new one (1.49) because it's got a lot of cool stuff. I tried to look for a forum on the boost site but didn't find one.

Share this post


Link to post
Share on other sites
Adding --toolset=msvc-9.0 to the bjam command line should (probably) do the trick. Obviously bjam must be invoked with the right environment variables set, easiest with the "Visual Studio 2008 Command Prompt" that should be available in your start menu.

Edit: That aside, while there are certainly important and useful parts of Boost that need to be compiled, isn't lexical_cast header-only?

Share this post


Link to post
Share on other sites
Boost can't be this hard to compile.......Im following the instructions on the site, i added an environment variable BOOST_ROOT and still can't get Boost-build to compile. there has to be an easier way to do this....

Share this post


Link to post
Share on other sites
I believe you can download pre-built versions of Boost. Read Boost's [url="http://www.boost.org/doc/libs/1_49_0/more/getting_started/windows.html"]Getting Started on Windows[/url] guide.

As BitMaster says, due to heavy use of templates, many Boost libraries are "header only". You don't need to build boost to use them. As such, all you need to do is merely add the Boost include directory to your project path, and you should be able to get lexical_cast<>.

Share this post


Link to post
Share on other sites
[quote name='rip-off' timestamp='1333632688' post='4928467']
I believe you can download pre-built versions of Boost. Read Boost's [url="http://www.boost.org/doc/libs/1_49_0/more/getting_started/windows.html"]Getting Started on Windows[/url] guide.

As BitMaster says, due to heavy use of templates, many Boost libraries are "header only". You don't need to build boost to use them. As such, all you need to do is merely add the Boost include directory to your project path, and you should be able to get lexical_cast<>.
[/quote]

well, i'd figure i'd use the FileSystem and other libraries of Boost to, pardon the pun, boost my code. as im trying to make my own engine and wanted to add scripting (basically like Ogre's material scripts or what not. Ogre uses boost for some of it's functions so i figured i'd try to use it to. also use FileSystem as an archive to add resources to a file then load them on demand, like companies have. you know.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this