![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Nicolas Alvarez wrote:
> template<typename E>
> void my_throw_exception(E& exc) {
> //do the backtrace() dance and store the results somewhere in exc
> throw exc;
> }
And yes, you do need the template. The 'throw' statement uses the *static*
type of the variable. So for example:
class MyError: public std::exception {};
void my_throw_exception(std::exception& exc) {
throw exc;
}
void foo(int test) {
switch (test) {
case 1:
throw std::exception();
break;
case 2:
throw MyError();
break;
case 3:
my_throw_exception(std::exception());
break;
case 4:
my_throw_exception(MyError()); // <- MyError gets sliced here
break;
}
}
int main() {
try {
foo(1);
} catch(MyError& e) {
std::cerr << "MyError thrown\n";
} catch(std::exception& e) {
std::cerr << "std::exception thrown\n";
}
}
It will only print "MyError thrown" if you pass 2 to foo().
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Nicolas Alvarez wrote:
> I think the most useful feature of RTTI is not typeid() to get a string, but
> dynamic_cast.
Yeah, but I've never seen an OO language that lacks that feature. :-)
Singling it out as something with a special name seems odd to me. I guess
the C++ standards authors just like making up their own names for things. It
would be like saying "Our language supports class-based OOP *and* virtual
functions!"
Don't things like GCC support dynamic_cast and virtual functions this even
if you compile without the switch that enables typeid? (Or with the switch
that turns it off? I seem to be finding conflicting info, altho I might be
looking at different compilers.)
It seems strange, too, that it would add any overhead at all, except maybe
one word of pointer to each class's code, to point to the type_info object.
Don't you need vtable pointers even if "RTTI" is turned off?
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Nicolas Alvarez wrote:
> I dunno... I think you might be able to do something like this:
I guess that would work for your own exceptions. If you get anyone else's
library, you're kind of screwed.
I've noticed that a lot with some languages - the runtime is such that it's
really hard to not have control of all the source code that goes into making
up the executable.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
> Nicolas Alvarez wrote:
>> I dunno... I think you might be able to do something like this:
>
> I guess that would work for your own exceptions. If you get anyone
> else's library, you're kind of screwed.
Actually, taking it one step farther, the place where it's hardest to debug
the failure is exactly where (a) it isn't your code to change, or (b) you
didn't expect to throw the exception (i.e., it got thrown for you).
Otherwise, you can put enough detail into the exception manually, or just
log the backtrace right there without dealing with exceptions at all.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Nicolas Alvarez wrote:
> I think the most useful feature of RTTI is not typeid() to get a string, but
> dynamic_cast.
I think my C++ fu is obviously very weak. I'm having a hard time seeing how
boost::any works, or at least what are the requirements and syntax of the
instantiation of it.
http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf
It sounds like "Employing the member template mechanism supports implicit
conversion from values of an arbitrary type into an any." means that I can
just say
any X = string("Hello");
and X will be an any<string> initialized to a copy of the std::string "Hello"?
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Actually, wouldn't this be clearer to do with virtual functions or pointers
> to functions anyway? Where does typeid make things better in that scenario?
> Isn't it just as easy to do something like
> class Alpha : Beta {
> ....
> virtual const char * me() { return "Alpha:Beta"; }
> ....
> }
It was you who complained that you have to write a "mySize()" function
in every single class derived from the base class if you wanted any useful
information about the actual object. I thought you wanted some way of
distinguishing the actual object without having to implement a function
in each class.
> Plus, you avoid the overhead of putting
> RTTI type_info on *every* class, most of which probably won't be registered
> that way?
If you have a virtual function in the class or any of its parent classes,
you already have RTTI info on it. typeid() itself doesn't add anything to
the classes.
It's also perfectly possible to ask for the typeid of a non-RTTI class
(ie. one which does not have any virtual functions). In that case you
simply get the typeid of the parameter (without the runtime checking of
whether the object is really of that type).
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> It was you who complained that you have to write a "mySize()" function
> in every single class derived from the base class if you wanted any useful
> information about the actual object.
You said that was a good idea, to prevent bypassing of modularity. :-)
OK, having thought about it, my criticisms in this case aren't really fair.
It isn't reflection, but it's not called reflection, so complaining that it
doesn't do what reflection does isn't too reasonable on my part. It would be
nice if it did, but I understand why it doesn't.
> If you have a virtual function in the class or any of its parent classes,
> you already have RTTI info on it. typeid() itself doesn't add anything to
> the classes.
OK, cool. That's what I thought. (Well, it probably/possibly allocates
space for the strings that name() returns, yes? But that's just one string
per class, so not really a problem.)
> It's also perfectly possible to ask for the typeid of a non-RTTI class
> (ie. one which does not have any virtual functions). In that case you
> simply get the typeid of the parameter (without the runtime checking of
> whether the object is really of that type).
Yeah. And I saw in boost::any they use it to get type information about
things like std::string, which you can't easily add virtual functions to in
order to support doing it yourself.
I guess it has some decent uses.
Thanks for continuing the conversation with me after I ticked you off earlier.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Tor Olav Kristensen wrote:
>
> http://en.wikipedia.org/wiki/Kool-Aid#.22Drinking_the_Kool-Aid.22
>
Much clearer explanation.
--
~Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> I surely can understand why such information could sometimes be useful,
> but it still sounds to me like you are accessing the internals of an object,
> bypassing its public interface, which is something that breaks the basic
> idea of modularity.
Here's an excellent example from Python:
http://qinsb.blogspot.com/2009/03/automatic-repr-and-eq-for-data.html
Translated for those who don't speak Python, this says "here's a mix-in
multi-inheritance class that provides a 'show as a string' function. It
examines the class and constructor arguments, so you can do something
like[1] this (using C++-ish syntax):
class Alpha : Beta, ThisMixinClass {
Alpha(int One, float Two) { ... }
}
And then call
Alpha alpha(23, 75.2);
and then you can say
string x = alpha.repr();
and have x get the value
"<class Alpha One=23 Two=75.2>"
Not really breaking encapsulation at all. Just adding as a method
functionality that you'd have to implement manually by hand in each class.
Not really breaking modularity any more than a template that relies on a
class having particular set of internal functions.
[1] The function __repr__() is what gets called on an instance to turn it
into a string that when you evaluate it in Python you get back the value. In
C++ terms, it would be like printing
std::string("Hello")
for a std::string whose value is "Hello", rather than just Hello.
__init__() is the constructor, and there's only one and you can't overload it.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On Mon, 09 Mar 2009 01:15:26 +0100, Darren New <dne### [at] san rr com> wrote:
>
> It sounds like "Employing the member template mechanism supports implicit
> conversion from values of an arbitrary type into an any." means that I
> can just say
>
> any X = string("Hello");
> and X will be an any<string> initialized to a copy of the std::string
> "Hello"?
Yes.
--
FE
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |