473,397 Members | 2,099 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

Handling errors within templated classes

I have a Stack class that works fine. In particular, when it
encounters an error, it cout's a msg and exits. However, I'd like to
change it to report the error and continue with dummy data as
necessary. My problem is how to construct dummy data consistent with
the type the class was instantiated with.

My class, stripped to it's essentials for my purpose here, is:

template <class T>
class Stack {
public:
T pop()
{
if ( top < 0 )
{
cout << "Error\n";
return WHAT;
}
return st[top--];
}
private:
int top;
T st[5];
};

How might the "return WHAT;" statement be coded to yield something
like:

if ( typeof(T) == int
doThis(0);
else
doThat("xxx");

It was recommended by one person that I check out "template
specialization", which I Googled. I found several offerings, but I
don't think they were applicable to the situation I'm trying to
address (but maybe I'm wrong).

I'm running MinGW on WinXP-Pro/.SP2.

Thanks in Advance,
Richard

Oct 30 '07 #1
8 1483
RichardOnRails wrote:
I have a Stack class that works fine. In particular, when it
encounters an error, it cout's a msg and exits. However, I'd like to
change it to report the error and continue with dummy data as
necessary. My problem is how to construct dummy data consistent with
the type the class was instantiated with.

My class, stripped to it's essentials for my purpose here, is:

template <class T>
class Stack {
public:
T pop()
{
if ( top < 0 )
{
cout << "Error\n";
return WHAT;
You can obtain a default value for T by using the default constructor
(provided T has one):

return ( T() );
}
return st[top--];
}
private:
int top;
T st[5];
};

How might the "return WHAT;" statement be coded to yield something
like:

if ( typeof(T) == int
doThis(0);
else
doThat("xxx");

It was recommended by one person that I check out "template
specialization", which I Googled. I found several offerings, but I
don't think they were applicable to the situation I'm trying to
address (but maybe I'm wrong).
I am not following the doThis() vs. doThat() example. In particular, I have
no idea what the "xxx" is doing there.
BTW: The stack class looks fishy. Poping off an empty stack should trigger
an assert(). If you really want the program to continue, you may opt for
throwing an exception. If you return invented data, client code has no
chance detecting that there way an error.

Also: a hard-coded limit size of 5 is (a) rather small and (b) not
necessary at all. Why don't you use std::stack<>?
Best

Kai-Uwe Bux
Oct 30 '07 #2
On Oct 30, 1:20 am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
RichardOnRails wrote:
I have a Stack class that works fine. In particular, when it
encounters an error, it cout's a msg and exits. However, I'd like to
change it to report the error and continue with dummy data as
necessary. My problem is how to construct dummy data consistent with
the type the class was instantiated with.
My class, stripped to it's essentials for my purpose here, is:
template <class T>
class Stack {
public:
T pop()
{
if ( top < 0 )
{
cout << "Error\n";
return WHAT;

You can obtain a default value for T by using the default constructor
(provided T has one):

return ( T() );
}
return st[top--];
}
private:
int top;
T st[5];
};
How might the "return WHAT;" statement be coded to yield something
like:
if ( typeof(T) == int
doThis(0);
else
doThat("xxx");
It was recommended by one person that I check out "template
specialization", which I Googled. I found several offerings, but I
don't think they were applicable to the situation I'm trying to
address (but maybe I'm wrong).

I am not following the doThis() vs. doThat() example. In particular, I have
no idea what the "xxx" is doing there.

BTW: The stack class looks fishy. Poping off an empty stack should trigger
an assert(). If you really want the program to continue, you may opt for
throwing an exception. If you return invented data, client code has no
chance detecting that there way an error.

Also: a hard-coded limit size of 5 is (a) rather small and (b) not
necessary at all. Why don't you use std::stack<>?

Best

Kai-Uwe Bux
Hi Kai-Uwe,

Thanks for your response.

Your questions/suggestions are well founded. However, I was using a
"toy" application to test alternative error-handling strategies. One
was to trap the error, display a msg and exit the app. However,
sometimes it's desirable to recover somehow from errors so that
additional errors can be exposed in a single pass through all the
calls in an app.

I finally came up with a way to do that. If you're still interested,
tell me what you think of the following example, which compiles with
the current version of MinGW's g++ and executes as intended: it
exposes two errors.

Regards,
Richard
// TemplateErrHandler.c++
// K:\_Projects\C++\MinGW\04a_TemplateErrHandler\

#include <string>
#include <iostream>
using namespace std;

template <class T>
class MyClass {
public:
MyClass() {}
T MyFn()
{
/* Invalid attampts:
return -1029384756; // Error flag
return "My Message"; // Error flag
*/

// Correct attempt:
cout << "ERROR: An error was detected; execution continuing\n";
T tObj;
return tOverloaded(tObj);
}
private:
int n;
int tOverloaded(int val) {return -1029384756;}
char* tOverloaded(string val){return "My Message";}
};

int main ()
{
MyClass<intintInstance;
cout << "From intInstance: " << intInstance.MyFn() << "\n";

MyClass<stringstrInstance;
cout << "From strInstance: " << strInstance.MyFn() << "\n";
}



Oct 30 '07 #3
Hi

RichardOnRails wrote:
I was using a "toy" application to test alternative error-handling
strategies. One was to trap the error, display a msg and exit the app.
However, sometimes it's desirable to recover somehow from errors so that
additional errors can be exposed in a single pass through all the
calls in an app.
Could you explain what kind of errors you want to detect?
I finally came up with a way to do that. If you're still interested,
tell me what you think of the following example, which compiles with
the current version of MinGW's g++ and executes as intended: it
exposes two errors.
Please explain in more detail what exactly you want to do, because I cannot
extract it from the example you give (nor from your previous posting...)
#include <string>
#include <iostream>
using namespace std;

template <class T>
class MyClass {
public:
MyClass() {}
T MyFn()
{
/* Invalid attampts:
return -1029384756; // Error flag
return "My Message"; // Error flag
*/

// Correct attempt:
cout << "ERROR: An error was detected; execution continuing\n";
T tObj;
return tOverloaded(tObj);
Okay... you create a default object tObj of type T. The value you return is
the return value of another overloaded function, named tOverloaded. This
return value does not at all depend on tObj (Question: Why do you create
the object, then?) Furthermore, for types T where no conversion to either
int or std::string exists, the instantiation of MyClass<T>::MyFn will fail.
}
private:
int n;
You _never_ use n. Why do you declare it?
int tOverloaded(int val) {return -1029384756;}
char* tOverloaded(string val){return "My Message";}
Don't use the string-literal-to-char-pointer conversion. It's only there for
C-compatibility (string literals are immutable). I think you wanted to
return string there. Furthermore: Is there _any_ reason why you return "My
Message" and -1029384756?
};

int main ()
{
MyClass<intintInstance;
cout << "From intInstance: " << intInstance.MyFn() << "\n";

MyClass<stringstrInstance;
cout << "From strInstance: " << strInstance.MyFn() << "\n";
}
So you are using MyClass<Tto return some arbitrary T value.

WHY?

And why don't you simply use:

template<typename TT some_value();
template<string some_value<string>() { return "My Message"; }
template<int some_value<int>() { return -1029384756; }

int main()
{
cout << "From int: " << some_value<int>() << "\n";
cout << "From str: " << some_value<string>() << "\n";
}

And what does this have to do with error handling and/or exposing two
errors?

Markus

Oct 30 '07 #4
On Oct 30, 9:42 am, Markus Moll <markus.m...@esat.kuleuven.ac.be>
wrote:
Hi

RichardOnRails wrote:
I was using a "toy" application to test alternative error-handling
strategies. One was to trap the error, display a msg and exit the app.
However, sometimes it's desirable to recover somehow from errors so that
additional errors can be exposed in a single pass through all the
calls in an app.

Could you explain what kind of errors you want to detect?
I finally came up with a way to do that. If you're still interested,
tell me what you think of the following example, which compiles with
the current version of MinGW's g++ and executes as intended: it
exposes two errors.

Please explain in more detail what exactly you want to do, because I cannot
extract it from the example you give (nor from your previous posting...)
#include <string>
#include <iostream>
using namespace std;
template <class T>
class MyClass {
public:
MyClass() {}
T MyFn()
{
/* Invalid attampts:
return -1029384756; // Error flag
return "My Message"; // Error flag
*/
// Correct attempt:
cout << "ERROR: An error was detected; execution continuing\n";
T tObj;
return tOverloaded(tObj);

Okay... you create a default object tObj of type T. The value you return is
the return value of another overloaded function, named tOverloaded. This
return value does not at all depend on tObj (Question: Why do you create
the object, then?) Furthermore, for types T where no conversion to either
int or std::string exists, the instantiation of MyClass<T>::MyFn will fail.
}
private:
int n;

You _never_ use n. Why do you declare it?
int tOverloaded(int val) {return -1029384756;}
char* tOverloaded(string val){return "My Message";}

Don't use the string-literal-to-char-pointer conversion. It's only there for
C-compatibility (string literals are immutable). I think you wanted to
return string there. Furthermore: Is there _any_ reason why you return "My
Message" and -1029384756?
};
int main ()
{
MyClass<intintInstance;
cout << "From intInstance: " << intInstance.MyFn() << "\n";
MyClass<stringstrInstance;
cout << "From strInstance: " << strInstance.MyFn() << "\n";
}

So you are using MyClass<Tto return some arbitrary T value.

WHY?

And why don't you simply use:

template<typename TT some_value();
template<string some_value<string>() { return "My Message"; }
template<int some_value<int>() { return -1029384756; }

int main()
{
cout << "From int: " << some_value<int>() << "\n";
cout << "From str: " << some_value<string>() << "\n";

}

And what does this have to do with error handling and/or exposing two
errors?

Markus
Hi,

Did you read the original post? I think that explains what I was
trying to do.

In Ruby, if I suspected that an object reference I had referred either
to a string or a number, I could write:

if obj.responds_to(zero?) puts "obj refers to a number"
else if obj.responds_to(upcase) puts "obj refers to a string"
else puts "Who knows what obj refers to?"

Stoustrup omitted such a capability from C++. I wanted effect such a
capability, and that's what my example does.

Maybe the following version will be more illustative.
--
Richard
// TemplateErrHandler.c++
// K:\_Projects\C++\MinGW\04a_TemplateErrHandler\

/*TEST RESULTS:
K:\_Projects\C++\MinGW\04a_TemplateErrHandler>g++ TemplateErrHandler.c
++

K:\_Projects\C++\MinGW\04a_TemplateErrHandler>a
ERROR: An error was detected; execution continuing
From intInstance: -1029384756
ERROR: An error was detected; execution continuing
From strInstance: My Message

K:\_Projects\C++\MinGW\04a_TemplateErrHandler>
*/

#include <string>
#include <iostream>
using namespace std;

template <class T>
class MyClass {
public:
MyClass() {}
T MyFn()
{
/* Invalid attampts:
return -1029384756; // Error flag
return "My Message"; // Error flag
*/

// Correct attempt:
cout << "ERROR: An error was detected; \n"
<< " execution will continue \n"
<< " by returning an artifical value.\n";
T tObj;
return tOverloaded(tObj);
}
private:
int n;
int tOverloaded(int val) {return -1029384756;}
char* tOverloaded(string val){return "My Message";}
};

int main ()
{
MyClass<intintInstance;
cout << "Return value from intInstance: " << intInstance.MyFn() << "\n
\n";

MyClass<stringstrInstance;
cout << "Return value from strInstance: " << strInstance.MyFn() << "\n
\n";
}
Oct 30 '07 #5
private:
int n;
You're right: I never used it. I originally thought I needed it, and
then forgot to remove it. I've done so now.
---
R.

Oct 30 '07 #6
RichardOnRails wrote:
On Oct 30, 1:20 am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
RichardOnRails wrote:
Your questions/suggestions are well founded. However, I was
using a "toy" application to test alternative error-handling
strategies. One was to trap the error, display a msg and
exit the app. However, sometimes it's desirable to recover
somehow from errors so that additional errors can be exposed
in a single pass through all the calls in an app.
There are two standard solutions for this problem, depending on
the types of errors you're interested in. If the error is
something "exceptional", i.e. something which won't normally
occur (like disk full or insufficient memory), you should
definitely raise an exception. If the error is something
"normal" (just about any errors in user input, for example), the
usual solution is to use some variant of the Barton and Nackman
"Fallible" idiom, perhaps extended to allow additional
information concerning the error. (There's an implementation
supporting extended error codes at my site:
http://kanze.james.neuf.fr/code-en.html, in the Basic
subsystem.)

Another, less frequently used idiom is to provide a callback.
I finally came up with a way to do that. If you're still
interested, tell me what you think of the following example,
which compiles with the current version of MinGW's g++ and
executes as intended: it exposes two errors.
It has two major flaws: the calling code doesn't know that there
was an error, and it outputs error messages to std::cout, which
is not necessarily where the client code wants them.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Oct 31 '07 #7
"Alf P. Steinbach" <al***@start.nowrote in news:13*************@corp.supernews.com:
>subsystem.)

That's good advice, but the advice about choosing exceptions or not
based on how "exceptional" the situation is IMO ungood advice -- no
matter that it is advice that's (mindlessly, and with reference to some
"authority") repeated by a majority of C++ programmers.

In addition to being so vague and subjective as to be worthless, it's
worthless because what can be "exceptional" in one context need not be
exceptional in some other context.

Instead, use exceptions where they provide clarity and are most
practical -- same advice as for use of loop constructs and other
language constructs.


I like the rule of thumb given on the boost site. Use exceptions if what you want is
stack unwinding, otherwise use an error code. In other words, if you generally expect
the immediate caller to handle the error in some way, don't use exceptions. If you
expect the error to be handled at a higher level than the immediate caller, then an
exception might well be the way to go.

joe
Oct 31 '07 #8
On Oct 31, 11:37 am, Joe Greer <jgr...@doubletake.comwrote:
"Alf P. Steinbach" <al...@start.nowrote innews:13*************@corp.supernews.com:
subsystem.)
That's good advice, but the advice about choosing exceptions or not
based on how "exceptional" the situation is IMO ungood advice -- no
matter that it is advice that's (mindlessly, and with reference to some
"authority") repeated by a majority of C++ programmers.
In addition to being so vague and subjective as to be worthless, it's
worthless because what can be "exceptional" in one context need not be
exceptional in some other context.
Instead, use exceptions where they provide clarity and are most
practical -- same advice as for use of loop constructs and other
language constructs.

I like the rule of thumb given on the boost site. Use exceptions if what you want is
stack unwinding, otherwise use an error code. In other words, if you generally expect
the immediate caller to handle the error in some way, don't use exceptions. If you
expect the error to be handled at a higher level than the immediate caller, then an
exception might well be the way to go.

joe
Hey guys, thanks for your additional ideas. I was just playing around
with a stack implementation I downloaded because I hadn't written any C
++ since I retired 6 years ago. Because it was using it merely as a
toy I added rudimentary error handling with messages directed to
stdout with immediate exit thereafter.

Then I thought I should play with the idea of adding a boolean DEBUG
symbol to allow reporting multiple error in a single session.
However, allowing continued execution after issuing an error message
proved problematical when the offending method's definition specified
a templated return type.

In the latter case, I had to be conjure a suitable dummy return
value. And that value had to be a literal of of the templated type.
I had in mind the ease with which I could that in Ruby, which is rich
in metaprogramming facilities. But nothing came to mind for C++.
Hence the post.

Then the idea of creating overload methods came to me and I was a
happy campler. So I'm signing off from this thread with thanks to all
respondents. I will keep your ideas in mind if I ever do serious C++
programming again.
--
Richard

Nov 1 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: WSeeger | last post by:
When creating a new class, is it encouraged to always include error handling routines within your LET and GET procedures? It's seems that most text books never seem to include much about error...
7
by: Noor | last post by:
please tell the technique of centralize exception handling without try catch blocks in c#.
11
by: Master of C++ | last post by:
Hi, I am writing a simulation package in C++, and so far I've written about 8000 lines of code and have about 30 classes. I haven't used C++ exceptions so far (for various reasons). The only two...
1
by: Noor | last post by:
Hi all, I am trying to catch all types of exceptions from a app regardless of whether it is in debugger mode( VS development environment) or run the.exe file outside the IDE. My App...
4
by: aaj | last post by:
Hi all I have an automated application, that runs in the middle of the night. If certain 'non system' errors occur (things like malformed files, missing files etc..), I send an automatic Email...
5
by: Michael | last post by:
Hello, I have a separate Database class that handles any database work that all my asp.net pages can use. My problem is, many times I use try/catch to catch errors, and I want to output these...
4
by: James Radke | last post by:
Hello, I am looking for guidance on best practices to incorporate effective and complete error handling in an application written in VB.NET. If I have the following function in a class module...
35
by: jeffc226 | last post by:
I'm interested in an idiom for handling errors in functions without using traditional nested ifs, because I think that can be very awkward and difficult to maintain, when the number of error checks...
2
by: domehead100 | last post by:
I have a templated class, CDerived: template <typename TValue, typename TDraw, typename TEdit ...> class CDerived : public CBase { TValue m_Value public: TValue& GetValue() const {
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.