C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Pointer to member: is this legal C++ code?
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Hans Guijt
Guest





PostPosted: Tue Aug 12, 2003 12:51 am    Post subject: Pointer to member: is this legal C++ code? Reply with quote



I am attempting to use pointers to members to build a "map" (not in the STL
sense) of a structure. I want to use this map to serialize the structure
automatically.

The tricky bit is that I don't want to repeat the serialisation code on each
struct I want to serialize, since there are quite a few of these (about 480)
and the result is likely to contain errors. Instead I want the compiler to
do the job for me. To accomplish this I've placed the serialisation code and
the array of pointers to members in a base class, and derive the structs I
want to serialize from this base class. In doing this, I end up with
pointers to members that are defined on the base class, but actually
pointing to a member of the derived class.

I have been unable to unearth a reason why this would be illegal, and
"common sense" and experimentation suggests it should work, but common sense
is not always the best guide when it comes to C++. So, is this a legal thing
to do? What theoretical and/or practical problems will I run into? Is there
a better solution?

This is some example code showing the bit I'm concerned about:

class cBase {
public:
int cBase::*MyIntPtr;
};

class cDerived: public cBase {
public:
cDerived ()
{ MyIntPtr = (int cBase::*)(&cDerived::MyInt); };

int MyInt;
};


Thanks for any insight provided,

Hans Guijt



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Richard Smith
Guest





PostPosted: Tue Aug 12, 2003 6:15 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote



Hans Guijt wrote:

Quote:
This is some example code showing the bit I'm concerned about:

class cBase {
public:
int cBase::*MyIntPtr;
};

Legal but pointless as cBase has no members of type int.

Quote:
class cDerived: public cBase {
public:
cDerived ()
{ MyIntPtr = (int cBase::*)(&cDerived::MyInt); };

No! &cDerived::MyInt is of type int cDerived::*, and you
can't cast it to a member of the base class like that.
Casting member pointers is the opposite way around to
casting objects: with an object you can cast a pointer to
derived to a pointer to base; with member pointers you cast
can cast a member pointer of a base class to a member
pointer to a base class.

If you think about it, this is the correct behaviour as it
prevents usage like the following

cBase* b = new cBase;
int cBase::* mp = &cDerived::MyInt;
int i = b->*mp; // Help! There is no such member

--
Richard Smith

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Markus Werle
Guest





PostPosted: Tue Aug 12, 2003 6:19 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote



Andrea Griffini wrote:

Quote:
On 11 Aug 2003 20:51:24 -0400, Hans Guijt <hguijt (AT) xs4all (DOT) nl> wrote:

The tricky bit is that I don't want to repeat the serialisation code on
each struct I want to serialize, since there are quite a few of these
(about 480) and the result is likely to contain errors. Instead I want
the compiler to do the job for me.

Allow me a question... did you ever consider to use code
generation ?

I did. Staying inside the C++ system for code generation
is a solution that is
- easier to maintain (yes, I see this every day),
- more reliable (errors get catched via the type system)
- faster at runtime (since C++ compiler starts optimization
in the code generation stage)
- simply cool

C++ allows a maximum of abstraction, use it.
If You need _generic_ Serialization, build it.
There _is_ a solution. If we do not find it by ourselves
we could ask Andrei Alexandrescou.


You mentioned C++ compilers which disagree with the template code.
The problem is not the code. The problem is that some people are
allowed to call their crap a "C++ compiler" without getting punished.

Fortunately the most important compiler _do_ understand C++
by now. This means that gcc-3.4 will be able to compile my code
like all EDG-based versions do since 2002.
So if You are on a widely used platform,
there is no problem left with disagreeing compilers.


Markus

--

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Hiram Berry
Guest





PostPosted: Tue Aug 12, 2003 11:03 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

"Richard Smith" <richard (AT) ex-parrot (DOT) com> wrote

Quote:
Hans Guijt wrote:

This is some example code showing the bit I'm concerned about:

class cBase {
public:
int cBase::*MyIntPtr;
};

Legal but pointless as cBase has no members of type int.
Surprisingly, not pointless. I was familiar with using Hans' method with

pointers to member *function* in order call derived class member functions
(including derived class accessors) bound to a (statically) base pointer,
but never considered that you could do the same with pointers to member
*data*. However when I checked the Standard it seems that there is no
reason that it won't work with pmd also.
Quote:

class cDerived: public cBase {
public:
cDerived ()
{ MyIntPtr = (int cBase::*)(&cDerived::MyInt); };

No! &cDerived::MyInt is of type int cDerived::*, and you
can't cast it to a member of the base class like that.
The paragraph on static_cast applied to pointers to member, 5.2.9/9 I think,

indicates that a pointer to derived class member can be upcast to a pointer
to base class member as long as there is a valid inverse standard
conversion. I couldn't find any distinction made there between pmf and pmd
types. In sanctioning the downcast, the paragraph delineating the standard
conversion of pointers to member, 4.11/2, just requires accessibility and a
nonvirtual base class; it also makes no distinction between pmd and pmf
types. Finally, the section on C-style casts, ie. "cast notation", section
5.4, indicates that the C-style cast in question should be interpreted as a
static_cast. Putting those elements together, Hans' cast looks okay to me.
Quote:
Casting member pointers is the opposite way around to
casting objects: with an object you can cast a pointer to
derived to a pointer to base; with member pointers you cast
can cast a member pointer of a base class to a member
pointer to a base class.
Richard, your explanation is valid reasoning for standard conversions, which

may be done implicitly (and nonanalytically) by the compiler. In that case
great care is exercised by language rules to avoid dereferencing a member
that doesn't actually exist, as you pointed out. Explicit casts however are
allowed to evade this relationship, with the understanding that the writer
of the cast expression is guaranteeing that the dynamic object really does
contain the member referred to by the pointer to member-- the compiler can't
know at compile time whether the member is valid or not; the writer promises
that it will be valid at run time, and the cast acts as a "manual override"
of normal behavior to give the writer this capability.

Hiram Berry




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
johnchx
Guest





PostPosted: Tue Aug 12, 2003 11:05 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

Richard Smith <richard (AT) ex-parrot (DOT) com> wrote

Quote:
Hans Guijt wrote:

This is some example code showing the bit I'm concerned about:

class cBase {
public:
int cBase::*MyIntPtr;
};

Legal but pointless as cBase has no members of type int.

class cDerived: public cBase {
public:
cDerived ()
{ MyIntPtr = (int cBase::*)(&cDerived::MyInt); };

No! &cDerived::MyInt is of type int cDerived::*, and you
can't cast it to a member of the base class like that.
Casting member pointers is the opposite way around to
casting objects:

You're probably thinking about the standard conversion (4.11/2).
Strangely enough, however, this is actually a perfectly legal static
cast (see 5.2.9/9). In particular, the standard says:

If class B contains the original member, or is a base or
derived class of the class containing the original member,
the resulting pointer to member points to the original
member.

Since cBase is a base class of the class (cDerived) that contains the
original member (cDerived::MyInt), the value of MyIntPtr is
well-defined.

If, however, the object for which the pointer to member is
dereferenced is of a dynamic type that does not have the pointed-to
member (e.g. cBase, cOtherDervied, etc.), the behavior of the
dereferncing expression is undefined (5.5/4). So it's probably best
to do a dynamic_cast on this before actually using MyIntPtr.

That said, if the "mapping" is really being initialized on a
per-object basis, as in the OP's code snippet, I'm not sure I see the
point of using pointers-to-members at all. Another poster has already
noted that it's possible to do the same thing with plain ol'
references (or pointers). And if you squint at that approach just
right, and it starts to look a lot like reinventing the vtable.

So...my own first cut at the problem would be to ask whether we can't
get what we need with plain old virtual functions?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andrea Griffini
Guest





PostPosted: Wed Aug 13, 2003 7:46 am    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

On 12 Aug 2003 14:19:10 -0400, Markus Werle
<numerical.simulation (AT) web (DOT) de> wrote:

Quote:
I did. Staying inside the C++ system for code generation
is a solution that is
- easier to maintain (yes, I see this every day),

Depending on the level of template trickery my impression
is that you can get code that's way more complex to
understand than simple imperative code generation (if
you want to understand the template trickery, of course;
if you want to use template trickery without understanding
it then it's another matter - you will just start crying
when somehing will not work (and it's when, not if) ).

Something as simple as "do this for every data member
of the class" is already out of the reach of templates.
Serialization is IMO a perfect example.

You can get somewhat close using inheritance to try
to emulate containment (ask Andrei for the details) ...
and honestly it's impressive what you can get by playing
with templates. Like it's impressive seeing someone that
can stand up on just one hand.

But IMO you shouldn't forget that you don't have to;
we normally have legs and we can stand while reading
a newspaper, and we can even jump and run.

Quote:
- more reliable (errors get catched via the type system)

What do you mean ? The generated code is passed
through the compiler and will eventually raise errors
that are quite descriptive. Note that the generated
code will probably be clear explicit non-template code.
How can be templates *more* reliable than this ?
Template code has some type variability that non-template
code has not: true that template can be better about type
checking than macros; but it's worse than non-template.

Also error reporting is a very typical example of areas
in which templates are quite weak. Normally with current
technology an error message in a template will have
the form of two screenfulls of babbling nonsense.
Error reporting in templates is such a weak spot that
there's even someone that is making a living on this
defect by selling you third party add-ons to help compilers!

Quote:
- faster at runtime (since C++ compiler starts optimization
in the code generation stage)

As a first impression I am honestly tempted to qualify
this statement as distilled nonsense; can you explain what
you mean ? Why could be explicit non-template code worse
than template code for the optimizer ?

Quote:
- simply cool

Oh. This is true. I was somewhat fooled by OP's request
in thinking that he was interested in something working;
and preferably simpler and better for the compiler too.

Looks like you're looking for something cool instead.

Probably the more complex and intricate is the cooler is;
your dream is - just guessing - writing code that no one
else in your workgroup will even barely understand. In this
case I completely agree templates can be better for that.

Quote:
C++ allows a maximum of abstraction, use it.

I think one should use abstraction only to the point of
return of investment. A typical case is IMO <algorithm>.
In many cases it's way more complex to try to describe an
abstraction in such a rigid language that just write the
implementation you want. The compiler is happier, the
code is faster, the collegues are less frustrated when
reading the code and error messages you get do actually
have a meaning. All way "uncool", I suppose.

Quote:
If You need _generic_ Serialization, build it.

IMO just a few in the world need generic serialization
(and they need it to sell it, not to use it).
Many need *specific* serialization and IMO sometimes this
can be an area in which code generators can do miracles.
It's something very stupid an repetitive and a program is
better for this kind of job.
Sure I think one should build a tool to avoid repeating
tasks; I am a true supporter the idea of of working to
avoid working. I think this is one of the souls of a
real programmer. I've to admit that I actually also happen
to be a terrible performer in repetitive brainless jobs.

Building using the wrong tool is another issue, however.
Like I said in the past I think templates are a impressive
new shiny hammer. A really nice one, honest. Still this
doesn't mean everything is now a nail.

Quote:
There _is_ a solution. If we do not find it by ourselves
we could ask Andrei Alexandrescou.

There are many solutions. Of course if you add artificial
limits you can end up in a place where there is only one
solution. Or even none, but an almost pratical quasi-solution
(for example inheritance as a mean for monkeying inclusion).

Quote:
You mentioned C++ compilers which disagree with the template code.
The problem is not the code. The problem is that some people are
allowed to call their crap a "C++ compiler" without getting punished.

So ? Sometimes there are other reasons for which a specific
platform must be used. C++ portability was a joke a few years
ago... now the situation is not terrible, especially if you
avoid the dark corners. But template trickery is one of
those corners.

Most portable libraries are currently *NOT* written in just
generic portable C++, but have a lot of #ifdefs and macros
to try to handle the diversity. Most of the times it can be
done, true, but I'm not paid to try to find new problems and
obstacles... my employer expects from me solutions.
If I can't get something working then my employer is not really
that happier if the problem is in a vendor part, especially if
I could have easily avoided the problematic area completely.
Let alone if they get to know that I entered deliberately
and without need an area that was a well-known source of
portability problems. And please don't make my employer hear
the comments about my code in the caffetteria; I'm not sure
if my employer will be that happy no one else - and not even
me in a few months - can understand what's in the code.

Quote:
Fortunately the most important compiler _do_ understand C++
by now. This means that gcc-3.4 will be able to compile my code
like all EDG-based versions do since 2002.
So if You are on a widely used platform,
there is no problem left with disagreeing compilers.

I guess all third party libraries for Win32 in the world
(for example for controlling special hardware) now support
g++/cygwin in addition to VC++ 6, right ?

Anyway, I hoped my suggestion helped. Seems you think it didn't.

Andrea

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Hans Guijt
Guest





PostPosted: Wed Aug 13, 2003 1:37 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

"David Turner" <david (AT) firepro (DOT) co.za> schreef in bericht
news:bha3io$grr$1 (AT) ctb-nnrp2 (DOT) saix.net...

Quote:
"Hans Guijt" <hguijt (AT) xs4all (DOT) nl> wrote in message
news:3F37ECC2.9020603 (AT) xs4all (DOT) nl...

This is some example code showing the bit I'm concerned about:

class cBase {
public:
int cBase::*MyIntPtr;
};

class cDerived: public cBase {
public:
cDerived ()
{ MyIntPtr = (int cBase::*)(&cDerived::MyInt); };

int MyInt;
};

There's nothing wrong with the idea, but perhaps I can offer a
simplification:

class Base {
protected:
int& intref;
};

class Derived: public Base {
int my_int;
public:
Derived(): intref(my_int) { }
};

My apologies; for the sake of this post I simplified the code a great deal.
I'm actually using a third class to store the member pointers, allowing me
to share the mapping information between instantiations of cDerived (of
which there are generally speaking enough that this is worth doing). The
various responses I received seem to (mostly) agree that doing this is
legal. If it had not been, this would have been my fallback solution.

Quote:
Apart from slightly cleaner syntax, this offers the advantage of a
potential
optimization: intref is likely to be eliminated altogether by the
compiler.

Another way to do this is of course through virtual accessor members
(although that might be a little heavy for a lightweight object). Yet
another technique which is fruitful is the Curiously Recurring Template:

template<class D
class Base {
public:
void serialize(ostream& of) {
D* subject = static_cast of << subject->fetchInt();
}
};

class Derived: public Base<Derived> {
int my_int;
public:
int fetchInt() const { return my_int; }
};

Unless I'm mistaken, don't these two solutions require that the base class
is already aware of the contents of the derived class? This is not a problem
if that contents consists of just a single integer, but I'm dealing with
much larger structures containing various types of data. Effectively, what
I'm trying to accomplish is getting the serialize() function without
actually having to write it for each class I want to serialize.


Regards,

Hans Guijt



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Markus Werle
Guest





PostPosted: Wed Aug 13, 2003 4:06 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

Andrea Griffini wrote:

Quote:
On 12 Aug 2003 14:19:10 -0400, Markus Werle
[email]numerical.simulation (AT) web (DOT) de[/email]> wrote:

I did. Staying inside the C++ system for code generation
is a solution that is
- easier to maintain (yes, I see this every day),

Depending on the level of template trickery my impression
is that you can get code that's way more complex to
understand than simple imperative code generation (if
you want to understand the template trickery, of course;
if you want to use template trickery without understanding
it then it's another matter - you will just start crying
when somehing will not work (and it's when, not if) ).

Yes, but libraries like boost::mpl or things that will
become a library like daixtrose, help a lot here.

Quote:
Something as simple as "do this for every data member
of the class" is already out of the reach of templates.
Serialization is IMO a perfect example.

Yes. Of course the serialization problem leaves a lot
of open questions if we uses templates. OTOH I hesitate
to give up the one-shot-within-the-language too soon.

Templates, when used wisely, can save You a lot of
headaches that only appear with distinct code generators.

Quote:
You can get somewhat close using inheritance to try
to emulate containment (ask Andrei for the details) ...
and honestly it's impressive what you can get by playing
with templates. Like it's impressive seeing someone that
can stand up on just one hand.

But IMO you shouldn't forget that you don't have to;
we normally have legs and we can stand while reading
a newspaper, and we can even jump and run.

We always have 2 choices here: generate code using the
C++ language itself or a separate code generator.

Quote:
- more reliable (errors get catched via the type system)

What do you mean ? The generated code is passed
through the compiler and will eventually raise errors
that are quite descriptive. Note that the generated
code will probably be clear explicit non-template code.
How can be templates more reliable than this ?
Template code has some type variability that non-template
code has not: true that template can be better about type
checking than macros; but it's worse than non-template.

Also error reporting is a very typical example of areas
in which templates are quite weak. Normally with current
technology an error message in a template will have
the form of two screenfulls of babbling nonsense.
Error reporting in templates is such a weak spot that
there's even someone that is making a living on this
defect by selling you third party add-ons to help compilers!

OK, I give You an example:
I have to write numerical simulation software.
For several different purposes I need to use the same method to
solve different specific sets of partial differential equations.

Since the task of discretization of partial differential
equations is quite complex and since I need to differentiate
the discretized equations with regard to every variable
contained, I decided to create a full blown automatic
discretiziation and differentiation.

So now you who probably are not familiar to finite-element
code generation could (if I gave my code to you) use my code
to generate time implicit fem-fct-solvers for an abritrary
system of partial differential equations within hours just by
typing code similar to:

Solver.AddPDE<2>(Differentiation<Time>(m_1)
+
Differentiation<Space_x>(Pow<2>(m_1)
/
rho + p)
+
Differentiation<Space_y>((m_1 * m_2) / rho)
== Null);

The rest is done _by_ _the_ _compiler_.
So the level of abstraction is at peak: we have a 1-to-1
correspondence between the equations and the code we need to
write.

If You make an error, e.g. try to multiply something with a
differentiation like in

rho * Differentiation<Time>(m_1)

the myriads of compiler errors you get also contain the string
"[ alot of undercores stripped ]
__ERROR_You_must_not_multiply_space_or_time_diffs_with_something_else__
[ alot of undercores stripped ]", so you understand your error
immediately.

Using the type system to catch these errors appears so much simpler to me
than if (thiscondition) { ... } else { throw ... } etc.

I just happened to write a rather rich file and command line parser with
default formulas etc. using boost::spirit where I decided to try to be
object oriented and also circumvent the type system a little bit. In that
code I had to build in some traps for common errors. I really got mad about
it. This is why I like code that exploits the C++ parser and the C++ type
system.


Quote:

- faster at runtime (since C++ compiler starts optimization
in the code generation stage)

As a first impression I am honestly tempted to qualify
this statement as distilled nonsense;

It's impressive how things can be formulated to pass the mods :-)

Quote:
can you explain what
you mean ? Why could be explicit non-template code worse
than template code for the optimizer ?

I take this back. I say: in theory, if I had a very good
highly optimizing compiler, this compiler might see through my
complete code generation routines and find a way to improve the
overall runtime performance, because optimization starts
during automatic discretization.

I have no proof for this, since I never tried to achieve my goals
with a separate code generator, but I heard some people are working
on code folding for templates, such that the dependency between
the number of instantiations of some generic algorithm and the
code size is no longer linear. Also my profiler tells me that
it's not the code generation part that contributes to runtime, but
rather things outside that part. So since the overhead tends to zero
with today's compilers I felt strong enough to make the statement.


Quote:
- simply cool

Oh. This is true. I was somewhat fooled by OP's request
in thinking that he was interested in something working;
and preferably simpler and better for the compiler too.

I think that my code generator is simply cool because it works
and is rather simple to use.

Quote:
Looks like you're looking for something cool instead.

I search for solutions that are generic such that they solve
a problem once for all times.


Quote:
Probably the more complex and intricate is the cooler is;
your dream is - just guessing - writing code that no one
else in your workgroup will even barely understand.

Please take a look at daixtrose. I worked hard on using
class and variable names that make sense to others.
My unpublished finite element code has great parts
that read like books:

if (!only_first_order)
{
//////////////////////////////////////////////////////////////////////
// recalculation of F_ with new data in final 1st order solution:
CalculateAntidiffusiveFluxes(Timestep_);
PrelimitAntidiffusiveFluxes();
LimitAntidiffusiveFluxes();

//////////////////////////////////////////////////////////////////////
// final solution
IterateFinalSolution(Timestep_, ConvergenceCriterion);
}

Quote:
In this
case I completely agree templates can be better for that.

Of course templates can be misused for obfuscated C++.
OTOH templates help a lot to separate concepts.
A list is a list, independent of whether it is a list
of apples or pees.

Quote:
C++ allows a maximum of abstraction, use it.

I think one should use abstraction only to the point of
return of investment.

Sometimes you need a long breath to finally end up with
something that is stronger, easier to use and faster
to apply to new situations.
Of course you have to pay for power, like one of
my Professors said: there is a conservation law for
the complexity and work to be done.

Quote:
A typical case is IMO <algorithm>.
In many cases it's way more complex to try to describe an
abstraction in such a rigid language that just write the
implementation you want. The compiler is happier, the
code is faster, the collegues are less frustrated when
reading the code and error messages you get do actually
have a meaning. All way "uncool", I suppose.

No. This is the way to approach it.
Once you find you write some code twice, then it is
time to write the template version.
I wonder why it took millions of people writing linked lists
before someone decided to write one for all times.
(BTW: writing a std::list is so much cheaper than writing
a code generator for a listSomeClass)

Also, in case you got familiar with templates
I think a good design or code description shows
the independence of the patterns and if you reflect this
independence in your code, you will get awarded for this
immediately.


Quote:

If You need generic Serialization, build it.

IMO just a few in the world need generic serialization
(and they need it to sell it, not to use it).

Ah.

Quote:
Many need specific serialization and IMO sometimes this
can be an area in which code generators can do miracles.

A template with controllable or specializable aspects
(keyword "policy") maybe too.

Quote:
It's something very stupid an repetitive and a program is
better for this kind of job.

Funny, but I use templates always to avoid code repetition.

Quote:
Sure I think one should build a tool to avoid repeating
tasks; I am a true supporter the idea of of working to
avoid working. I think this is one of the souls of a
real programmer. I've to admit that I actually also happen
to be a terrible performer in repetitive brainless jobs.

Building using the wrong tool is another issue, however.
Like I said in the past I think templates are a impressive
new shiny hammer. A really nice one, honest. Still this
doesn't mean everything is now a nail.

But since I saw typelist I really feel like there is no reason to avoid
templates for the serialization task. Although I cannot iterate the members
in a class I can iterate the members in a typelist. Therefore if I had to do
serialization my first attempt always would be some template stuff.

OTOH I agree that some external code generator might quickly
help here a lot, but I always fear the maintenance problem.

Quote:
There is a solution. If we do not find it by ourselves
we could ask Andrei Alexandrescou.

There are many solutions. Of course if you add artificial
limits you can end up in a place where there is only one
solution. Or even none, but an almost pratical quasi-solution
(for example inheritance as a mean for monkeying inclusion).

You mentioned C++ compilers which disagree with the template code.
The problem is not the code. The problem is that some people are
allowed to call their crap a "C++ compiler" without getting punished.

So ? Sometimes there are other reasons for which a specific
platform must be used. C++ portability was a joke a few years
ago... now the situation is not terrible, especially if you
avoid the dark corners. But template trickery is one of
those corners.

The point I wanted to make is that I expect C++ portability to
reach the level C and Fortran have today within a couple of years.
So _all_ language aspects of C++ should be considered for new code
disregarding the crap compilers (which I also expect to vanish soon)

Quote:
Most portable libraries are currently NOT written in just
generic portable C++, but have a lot of #ifdefs and macros
to try to handle the diversity. Most of the times it can be
done, true, but I'm not paid to try to find new problems and
obstacles... my employer expects from me solutions.
If I can't get something working then my employer is not really
that happier if the problem is in a vendor part, especially if
I could have easily avoided the problematic area completely.
Let alone if they get to know that I entered deliberately
and without need an area that was a well-known source of
portability problems. And please don't make my employer hear
the comments about my code in the caffetteria;

I agree with your intention here.
I simply do not see a contradiction anymore.
When e.g. Qt first was published it was wise to write rather
non-templated code and create private container substitutes
for the STL. As of today I believe it would be wise to rewrite
the code step by step reverting back to std:: and also
exploiting the stuff that brings speed.

Quote:
I'm not sure
if my employer will be that happy no one else - and not even
me in a few months - can understand what's in the code.

Since Vandevoorde/Josuttis finally took the time to
publish a "complete guide" (which I think is the first time
a book deserves such a 2nd title) no one is allowed to
cry anymore at the sight of some <> brackets.

Also I do not see how avoiding templates should hinder anyone
to write obfuscated code. C++ _is_ ugly, yes, but after some
weeks you get the used to <> like you got used to {} and stopped
to forget the ; at class end.


Quote:
Fortunately the most important compiler do understand C++
by now. This means that gcc-3.4 will be able to compile my code
like all EDG-based versions do since 2002.
So if You are on a widely used platform,
there is no problem left with disagreeing compilers.

I guess all third party libraries for Win32 in the world
(for example for controlling special hardware) now support
g++/cygwin in addition to VC++ 6, right ?

Anyway, I hoped my suggestion helped. Seems you think it didn't.

I think it did. I just wanted to mention I had made very good
experience with the opposite method, so it should not be
abandoned too soon. Probably my wordings shadowed this intent, sorry.


best regards,


Markus

--

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
johnchx
Guest





PostPosted: Wed Aug 13, 2003 10:47 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

"Hans Guijt" <hguijt (AT) inter (DOT) nl.net> wrote

Quote:
So the solution I came up with involves an array of unions of pointers to
member. This is a pretty good solution: I need just a single function to
initialize the array (meaning I need to do a limited amount of work), I can
share the array between instantiations of derived classes, and I can add any
operation on the structures that I desire by simply adding a single new
function. The solution provides me with both type safety and readability in
the client code, since it can simply access the payload as if it were any
normal C++ class.

This sounds very interesting. For some reason, though, I'm having
trouble visualizing how it works in practice. For example, how does
cBase know the type of the result of dereferencing one of the pointers
in the array? Perhaps posting a snippet of the serialization code,
showing how cBase selects a member from the union and uses the result
would help me see what's going on.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Aatu Koskensilta
Guest





PostPosted: Thu Aug 14, 2003 12:27 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

Markus Werle wrote:

Quote:
Andrea Griffini wrote:


On 11 Aug 2003 20:51:24 -0400, Hans Guijt <hguijt (AT) xs4all (DOT) nl> wrote:

The tricky bit is that I don't want to repeat the serialisation code on
each struct I want to serialize, since there are quite a few of these
(about 480) and the result is likely to contain errors. Instead I want
the compiler to do the job for me.

Allow me a question... did you ever consider to use code
generation ?


I did. Staying inside the C++ system for code generation
is a solution that is
- easier to maintain (yes, I see this every day),
- more reliable (errors get catched via the type system)
- faster at runtime (since C++ compiler starts optimization
in the code generation stage)
- simply cool

C++ allows a maximum of abstraction, use it.
If You need _generic_ Serialization, build it.
There _is_ a solution. If we do not find it by ourselves
we could ask Andrei Alexandrescou.

There is no solution as long as we're restricted to the current C++
standard. (At least not one that doesn't require one to build
compile-time representations for the types to be serialised.)

What I'd like to see was standard support for something like
type_description<T>, which would contain fields like
type_description<T>::is_pod, type_description<T>::base_classes,
type_description<T>::member_functions,
type_description<T>::public::members, &c.

--
Aatu Koskensilta (aatu.koskensilta (AT) xortec (DOT) fi)

"Wovon man nicht sprechen kann, daruber muss man schweigen"
- Ludwig Wittgenstein, Tractatus Logico-Philosophicus

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Markus Werle
Guest





PostPosted: Fri Aug 15, 2003 9:15 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

Andrea Griffini wrote:

Quote:
On 13 Aug 2003 12:06:16 -0400, Markus Werle
[email]numerical.simulation (AT) web (DOT) de[/email]> wrote:

Yes, but libraries like boost::mpl or things that will
become a library like daixtrose, help a lot here.

Suggesting using a template library is one thing.
Suggesting writing a template library is another.

Templates, when used wisely, can save You a lot of
headaches that only appear with distinct code generators.

Can you make an example of headache ?

Parsing.
Writing a parser that handles every situation is hard.
Using the C++ type system and exploiting the C++ parser
saves you a lot.
Since the parser is missing in my approach, I do not
have to maintain one. This is what I do within daixtrose.
The expression is parsed using template metaprogramming,
but most of the time I can simply rely on the C++ rules.


Quote:
We always have 2 choices here: generate code using the
C++ language itself or a separate code generator.

There would be a choice if templates could iterate
over the members. But serialization is out of the reach
of template (unless of course you don't want to iterate
over the members but try to change my needs on an iteration
over the base classes).

I disagree and by the same time stay in debt regarding
a counter example due to lack of time.

Quote:
[...]
OK, I give You an example:
I have to write numerical simulation software.
For several different purposes I need to use the same method to
solve different specific sets of partial differential equations.

I thought the discussion was about serialization and
member enumeration in general.

I thought it was about code generation no matter what
the problem/task is.

Quote:
I for example think that
template are very nice for dimensionality parametrization;
even if the results of a few experiments I made about
efficency of the generated code are if compared to hand
unrolled code not that good (not terrible, but still worse).

With today's compilers you get it down to factor 1.6 in numerics.

Quote:
I agree that in *theory* compilers can see what's common
in templates and merge those parts.
Unfortunately this is not what compiler technology gives
us today... and the code bloating risk is always here to
remember us this fact.
Just try to do the simplest experiment with g++...

Bah! Which version? Which command-line options?
I was talking with Intel C++ 7.1 (using IPO) in mind.

Quote:
I think that my code generator is simply cool because it works
and is rather simple to use.

And it does serialization iterating over the members ?

No, but it shows that an in-language code generator can be
the Right Thing to do. Would _you_ use the compiler
to differentiate expressions? I do.

Quote:
I search for solutions that are generic such that they solve
a problem once for all times.

So much damage to the human race has been done by who
was seeking the definitive solution. I think there's
no definitive solution (especially because there's no
definitive problem).

I said: _a_ problem. There is no definitive solution, but
probably one that can be reused. This is what templates are
all about.

Quote:
A list is a list, independent of whether it is a list
of apples or pees.

There are a lot of variations even on a list, and the
view given by the standard library is just one possible
view, that in some context doesn't fit well. I use a
lot of linked lists in my code, but I rarely used std::list.

I had some crazy experience with std::map:
I use std::map to store entries of a sparse matrix.
Since this part of my code really is the expensive part
I tried to substitute std::map with things like Loki::AssocVector
and to use other allocators. And guess: std::map always wins.

So all those SpecialPurposeMyOneIsTheBetterOne container
writers of the world got beaten by a std::container.
That was new to me.

Quote:
std::vector is IMO much more neutral and generally useful.

Yep.

Quote:
Once you find you write some code twice, then it is
time to write the template version.

Only if the template use is really saving something.
I for example think C++ for_each is worse than a for
loop for several reasons (this is not true for other
languages, of course, but it's IMO true for C++).

When I changed a container inside some class and found
out that the algo code still compiled and worked(!) due
to the use of begin() and end() memfuns and this std::algorithm stuff
I began to love these std::algorithms a lot.

together with boost::lambda/function they sometimes also
make code cleaner and easier to understand.

Quote:
I wonder why it took millions of people writing linked lists
before someone decided to write one for all times.
(BTW: writing a std::list is so much cheaper than writing
a code generator for a listSomeClass)

I normally write my simple linked lists by hand.

Wow!

Quote:
[..]
But back to serialization... ;)

But since I saw typelist I really feel like there is no reason to avoid
templates for the serialization task. Although I cannot iterate the
members in a class I can iterate the members in a typelist. Therefore if I
had to do serialization my first attempt always would be some template
stuff.

Good luck. I don't see that a reasonable solution
because there are much better ones... they're not 100%
C++, so ? I think it's better that way than ending up
with a pure 100% C++ version that solves a problem
roughly similar to what I wanted to solve and that
also has a lot of pratical problematic issues.

Your decision as you like it.

Quote:
The point I wanted to make is that I expect C++ portability to
reach the level C and Fortran have today within a couple of years.
So _all_ language aspects of C++ should be considered for new code
disregarding the crap compilers (which I also expect to vanish soon)

Including template recursion 40 levels deep ?

No, sometimes more than 200. Recursion is fine.

Quote:
Including
taking forever to compile C++ code written that way ?

Compile time is nonlinear with time:
The power of our computers increase exponentially
and compiler vendors finally found out how to deal with
templates. Every new compiler version cuts down compile time
by at least 10%.
I use templates because the runtime performance
is better when I calculate it at compile time. This pays off
most of the times.

Quote:
[...]
Still I wouldn't so sure I necessarely will end up
believing that pushing using a 40 leves deep hierarchy
down the throat of my compiler when what I wanted was
just a list of 40 members is a sensible thing to do.

40 members in a class looks like a candidate for a redesign.
Especially if it is something which calls serialization.
OTOH size does not matter. The solution should scale well.
So probably the OP will reach his goal earlier with
an external code generator, but I still think the in-C++
approach is achievable and may have some advantage.

Quote:
I think it did. I just wanted to mention I had made very good
experience with the opposite method, so it should not be
abandoned too soon. Probably my wordings shadowed this intent, sorry.

You had good experiences in other areas (dimensionality
and policy) and not in members enumeration.

If the set of possible member names and types is finite
I see a good chance to have a generic C++ solution.
fast.

Quote:
May be you're right and that's a good path ... but my gut
feeling is that this is a circus thing, not for serious use.

Compile time differentiation like in daixtrose looks like
a circus thing but is used in production code.


Markus


--

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Markus Werle
Guest





PostPosted: Fri Aug 15, 2003 9:16 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

Aatu Koskensilta wrote:


Quote:
What I'd like to see was standard support for something like
type_description<T>, which would contain fields like
type_description<T>::is_pod,

http://www.boost.org/libs/type_traits/index.htm

Quote:
type_description<T>::base_classes,

If the set of base classes is finite You can check for this.

Quote:
type_description<T>::member_functions,
type_description<T>::public::members, &c.

You want those as typelist?

Markus




--

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andy Sawyer
Guest





PostPosted: Sun Aug 17, 2003 11:40 am    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

In article <bhifqm$10jsa$1 (AT) ID-153032 (DOT) news.uni-berlin.de>,
on 15 Aug 2003 17:15:58 -0400,
Markus Werle <numerical.simulation (AT) web (DOT) de> wrote:

Quote:
Andrea Griffini wrote:

On 13 Aug 2003 12:06:16 -0400, Markus Werle
[email]numerical.simulation (AT) web (DOT) de[/email]> wrote:

The point I wanted to make is that I expect C++ portability to reach
the level C and Fortran have today within a couple of years. So
_all_ language aspects of C++ should be considered for new code
disregarding the crap compilers (which I also expect to vanish soon)

Including template recursion 40 levels deep ?

No, sometimes more than 200. Recursion is fine.

Not if you care about portability, it's not. (see 14.7.1p14 and Annex B
for details)

Regards,
Andy S
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
llewelly
Guest





PostPosted: Mon Aug 18, 2003 10:29 am    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

Markus Werle <numerical.simulation (AT) web (DOT) de> writes:

Quote:
Andrea Griffini wrote:
[snip]
Including template recursion 40 levels deep ?

No, sometimes more than 200. Recursion is fine.
[snip]


The standard only requires 17 levels be supported. (Most compilers
support much more, when given appropriate flags.)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Markus Werle
Guest





PostPosted: Mon Aug 18, 2003 5:26 pm    Post subject: Re: Pointer to member: is this legal C++ code? Reply with quote

Andy Sawyer wrote:

Quote:
In article <bhifqm$10jsa$1 (AT) ID-153032 (DOT) news.uni-berlin.de>,
on 15 Aug 2003 17:15:58 -0400,
Markus Werle <numerical.simulation (AT) web (DOT) de> wrote:

Andrea Griffini wrote:

On 13 Aug 2003 12:06:16 -0400, Markus Werle
[email]numerical.simulation (AT) web (DOT) de[/email]> wrote:

The point I wanted to make is that I expect C++ portability to reach
the level C and Fortran have today within a couple of years. So
_all_ language aspects of C++ should be considered for new code
disregarding the crap compilers (which I also expect to vanish soon)

Including template recursion 40 levels deep ?

No, sometimes more than 200. Recursion is fine.

Not if you care about portability, it's not. (see 14.7.1p14 and Annex B
for details)

You got me.
I always wondered how one could circumvent this restriction
of the standard and appreciate any link or hint to some
technique to achieve this.

OTOH all modern compilers seem to support this without any
trouble - which I find a logical consequence of having as much
symmetry as possible between the runtime and the compile time system.
Or: Ain't the limitation a defect anyway?
Think of "for (size_t i = 1; i != 18; ++i);"


Markus

--

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.