Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++0x Wish list

9 views
Skip to first unread message

Tom Puverle

unread,
May 7, 2002, 10:23:11 PM5/7/02
to
I am trying to put together a wish list of language extensions that people
would like to see in C++0x.
Any contributions and opinions on what is likely to make it into the new
standard would be greatly appreciated...
Let me set the ball rolling:

TEMPLATES:
- templatized typedef
- typeof()
- function template partial specialisation

RTTI:
- add a "class()" member function to type_info
that returns a compiler independent unique identifier for the class of the
object

Thanks.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Pete Becker

unread,
May 9, 2002, 12:55:33 PM5/9/02
to
Tom Puverle wrote:
>
> I am trying to put together a wish list of language extensions that people
> would like to see in C++0x.

Let me suggest a different approach. Instead of asking about language
features, put together a list of problems that aren't easily solved in
the language as it exists today. Language features aren't an end in
themselves, but are a way of solving problems. Focusing initially on
problems rather than solutions will lead to a better set of solutions.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Garry Lancaster

unread,
May 9, 2002, 12:55:00 PM5/9/02
to
Tom Puverle:

> TEMPLATES:
> - templatized typedef
> - typeof()
> - function template partial specialisation

These have all been pretty well discussed both on this
newsgroup and elsewhere.

> RTTI:
> - add a "class()" member function to type_info
> that returns a compiler independent unique identifier for the class of the
> object

You know that there's already a type_info::name()
member function? Its value isn't compiler independent
though and it would be nice if it were (particularly
for things like serialization frameworks) It isn't
quite as straightforward as it seems though. Off
the top of my head we would have to consider:

- namespaces. Is the namespace of a type part
of its name? If so, how is membership of the
anonymous namespace signified?

- typedefs. Presumably we use the original name
of the class not any typedef-alias in use? (Or, for
that matter any namespace-alias.)

- Templates. How to specify template parameters
used for a class template instantiation.

None of this is rocket science. You would think
a consensus could be reached. Still, maybe I'm
missing something.

Kind regards

Garry Lancaster
Codemill Ltd
Visit our web site at http://www.codemill.net

John G Harris

unread,
May 9, 2002, 3:47:42 PM5/9/02
to
In article <a7qC8.4520$xb4.7...@news6-win.server.ntlworld.com>, Garry
Lancaster <glanc...@ntlworld.com> writes
>Tom Puverle:
<snip>

>> RTTI:
>> - add a "class()" member function to type_info
>> that returns a compiler independent unique identifier for the class of the
>> object
<snip>

>Off
>the top of my head we would have to consider:
>
>- namespaces. Is the namespace of a type part
>of its name? If so, how is membership of the
>anonymous namespace signified?
>
>- typedefs. Presumably we use the original name
>of the class not any typedef-alias in use? (Or, for
>that matter any namespace-alias.)
>
>- Templates. How to specify template parameters
>used for a class template instantiation.
>
>None of this is rocket science. You would think
>a consensus could be reached. Still, maybe I'm
>missing something.

There may be extra considerations, depending on what is being wished
for.

- If the application is spread over thousands of computers do we want my
mumble::Thing class and your mumble::Thing class in different computers
to have different identifiers?

- What about the standard library? Does vector<int> always have the same
identifier, or does it depend on whose library it comes from?

John
--
John Harris
mailto:jo...@jgharris.demon.co.uk

David Sachs

unread,
May 9, 2002, 11:03:14 PM5/9/02
to
Here are some extensions that I would like to see in a future version of the
C++ language.

1) Improved numeric limits such as the smallest and largest number of each
floating point type, whose inverse is also valid and normalized.

2) A way to use placement operator delete and operator delete[] for memory
allocated with a placement operator new.

3) A way to directly specify in a class declaration, that the class cannot
be used as a base class. This would permit treating all the class's methods
as non-virtual and improve code that uses the class.

--
The Klingons' favorite food was named by the first Earthling to see it.
"Pete Becker" <peteb...@acm.org> wrote in message
news:3CDA7DBA...@acm.org...

Scott Robert Ladd

unread,
May 9, 2002, 11:14:58 PM5/9/02
to
"Pete Becker" <peteb...@acm.org> wrote in message
news:3CDA7DBA...@acm.org...
> Let me suggest a different approach. Instead of asking about language
> features, put together a list of problems that aren't easily solved in
> the language as it exists today.


Bravo, Pete!

It seems like people want to throw in the kitchen sink without figuring out
if we need one -- or if, perhaps, we can put one together with the existing
plumbing.

--
Scott Robert Ladd
Coyote Gulch Productions -- http://www.coyotegulch.com
No ads. Just very free (and unusual) code and articles

Eric Niebler

unread,
May 10, 2002, 4:35:10 AM5/10/02
to

"Pete Becker" <peteb...@acm.org> wrote in message
news:3CDA7DBA...@acm.org...
> Instead of asking about language
> features, put together a list of problems that aren't easily solved in
> the language as it exists today.

Good suggestion.

Not too long ago, this code appeared in a column by a well-respected C++
guru.

template<class CharT, class Traits>
basic_ostream<CharT, Traits>& operator<<
( basic_ostream<CharT, Traits>& o, const Num& n )
{
long value = n.Value();
basic_string<CharT, Traits> s;

CharT digits []
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

<snip>

The code compiles fine when CharT==char, but if it is anything else the
compile breaks on the declaration of the digits array. Basically, string
literals and template code don't mix. The fact that this error slips into
the code of even the most seasoned experts demonstrated that it's a real
problem.

In the past, I have hacked around the problem like this:

CharT digits [] = { '0', '1', '2', ... };

but this is (a) tedius, (b) verbose, and (c) wrong. It's wrong becuase if
CharT==wchar_t, then there is no guarantee that assigning a char to a
wchar_t yields anything meaningful.

Of course, I could defer the string conversion to run-time and use a locale,
but that's not guaranteed to yield the same results as if the compiler did
the conversion, as it would have to for L"..." wide string literals.

Does anybody have a solution for this?

Thanks,
Eric

David Rasmussen

unread,
May 10, 2002, 4:37:12 AM5/10/02
to
Scott Robert Ladd wrote:
> "Pete Becker" <peteb...@acm.org> wrote in message
> news:3CDA7DBA...@acm.org...
>
>>Let me suggest a different approach. Instead of asking about language
>>features, put together a list of problems that aren't easily solved in
>>the language as it exists today.
>
>
>
> Bravo, Pete!
>
> It seems like people want to throw in the kitchen sink without figuring out
> if we need one -- or if, perhaps, we can put one together with the existing
> plumbing.
>

I agree that the approach Pete suggests is good. But whether something
can be done with the existing language or not, is not a good measure of
anything IMO. A very good example that always spring to mind when I'm
thinking about the future of C++, is Alexandrescu's Loki library. When I
read Modern C++ Design, I was first impressed (I still am). But then I
began to think: Why should it be so hard to express something as useful
and natural as these concepts? In my opinion Loki is only scratching the
surface of techniques that need much more language support. I am of the
view that as much work as possible, should be left to the compiler
implementor. And there are many many examples of things that can be done
today, but that really shouldn't be done my programmers but by compiler
implementors. The modularity on file level in C++ is based on something
as trivial as a preprocessor and header files. Why? A programmer should
only need to state the concepts and their interfaces, and the interface
of a module. No need to deal with header files, guards etc. Another
example is forward declaration. Why should the programmer go out of his
way to help the compiler, instead of focussing on the problem at hand? A
compiler could easily deal with this.

Generally, there are a lot of useful things that the language and the
compilers could support, while still maintaining the zero-overhead
principle, static type safety etc. The entire concept of "compile-time
programming" as done in Loki and Modern C++ Design, could have much more
language support.

Making a language better is not always about adding normal language
features. One of the things I would like very much in C++, that is
impossible now, is to be able to disable a language feature. That is, I
would like to be able to state somehow in my program, that old-style
casts are not allowed. I have had bugs that came from the fact that
Identifier(something) can be a cast, but also a function or macro call.
Of course, this is all my fault, but it would be nice if the language
had features for helping me not make such a bug, without me having to
resort to complex abstraction features when they aren't needed. In
general, if C++ was able to specify what features and constructs were
allowed or not, there could be defined strictness-levels, as in other
transitional languages that have to be backward-compatible, but also
wants to suggest a new and better way of doing things (like XHTML, no
comparison BTW). This way, there could simply be a strictness level that
I as a programmer was able choose. Sometimes it is a very good thing to
be restricted, if it means that you're restricted from making bugs.

I know this post is a little disorganized, but I am not trough thinking
about this (who is?). All I'm saying is, that C++ could have a lot more
features that would make the programmer focus on the job, and the
compiler on the technicalities, while still retaining it's zero-overhead
principle, typechecking and native compilation features.

/David

Steve Heller

unread,
May 10, 2002, 11:26:28 AM5/10/02
to
"David Sachs" <sa...@fnal.gov> wrote:

>Here are some extensions that I would like to see in a future version of the
>C++ language.
>
>1) Improved numeric limits such as the smallest and largest number of each
>floating point type, whose inverse is also valid and normalized.
>
>2) A way to use placement operator delete and operator delete[] for memory
>allocated with a placement operator new.
>
>3) A way to directly specify in a class declaration, that the class cannot
>be used as a base class. This would permit treating all the class's methods
>as non-virtual and improve code that uses the class.

I would like the standard to guarantee that deleting a derived class
object through a base class pointer will work even if the destructor
is not virtual, so long as the derived class adds no data members.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

Alexander Terekhov

unread,
May 10, 2002, 11:27:34 AM5/10/02
to

Scott Robert Ladd wrote:
>
> "Pete Becker" <peteb...@acm.org> wrote in message
> news:3CDA7DBA...@acm.org...
> > Let me suggest a different approach. Instead of asking about language
> > features, put together a list of problems that aren't easily solved in
> > the language as it exists today.
>
> Bravo, Pete!

Are things meant to provide MORE convenience/result in LESS
"convoluted"/weird C++ "solutions" (and I'm NOT talking about
templates/"generic-meta-programming", BTW ;-)) also meant to
be among the "problems that aren't easily solved in the
language as it exists today"?

Oh! BTW, Folks, is THIS "a problem":

ISO/IEC 14882:1998(E) © ISO/IEC Pg. 642:

"~sentry();

4 If ((os.flags() & ios_base::unitbuf) && !uncaught_exception())
is true, calls os.flush()."

<?> ;-) ;-)

regards,
alexander.

James Kuyper Jr.

unread,
May 10, 2002, 11:27:02 AM5/10/02
to
David Sachs wrote:
>
> Here are some extensions that I would like to see in a future version of the
> C++ language.
....

> 2) A way to use placement operator delete and operator delete[] for memory
> allocated with a placement operator new.

That issue doesn't come up; there's no such thing as "memory allocated
with a placement operator new". That's what makes it a placement
operator new - the memory has already been allocated by the time that
you use the 'new' operator to construct an object in it.

Francis Glassborow

unread,
May 10, 2002, 1:17:38 PM5/10/02
to
In article <0QGC8.244555$nc.36...@typhoon.tampabay.rr.com>, Scott
Robert Ladd <sc...@coyotegulch.com> writes

>"Pete Becker" <peteb...@acm.org> wrote in message
>news:3CDA7DBA...@acm.org...
>> Let me suggest a different approach. Instead of asking about language
>> features, put together a list of problems that aren't easily solved in
>> the language as it exists today.
>
>
>Bravo, Pete!
>
>It seems like people want to throw in the kitchen sink without figuring out
>if we need one -- or if, perhaps, we can put one together with the existing
>plumbing.

Actually the evolution work group of WG21 is drafting a format for
submissions which does exactly this, requires that a proposal includes
the problem it is intended to solve. Hopefully by autumn we will both
guidelines and examples available.


--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Francis Glassborow

unread,
May 10, 2002, 1:18:10 PM5/10/02
to
In article <3cdb0a06$1...@news.microsoft.com>, Eric Niebler
<eri...@microsoft.com> writes

>In the past, I have hacked around the problem like this:
>
> CharT digits [] = { '0', '1', '2', ... };
>
>but this is (a) tedius, (b) verbose, and (c) wrong. It's wrong becuase if
>CharT==wchar_t, then there is no guarantee that assigning a char to a
>wchar_t yields anything meaningful.
>
>Of course, I could defer the string conversion to run-time and use a locale,
>but that's not guaranteed to yield the same results as if the compiler did
>the conversion, as it would have to for L"..." wide string literals.
>
>Does anybody have a solution for this?

This is part of the more extensive problem of providing full support for
literals which is one of the problems that the evolution workgroup has
already identified as needing consideration.


--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

Francis Glassborow

unread,
May 10, 2002, 1:17:59 PM5/10/02
to
In article <3CDB847F...@gmx.spam.egg.sausage.and.spam.net>, David
Rasmussen <david.r...@gmx.spam.egg.sausage.and.spam.net> writes

>I agree that the approach Pete suggests is good. But whether something
>can be done with the existing language or not, is not a good measure of
>anything IMO. A very good example that always spring to mind when I'm
>thinking about the future of C++, is Alexandrescu's Loki library. When
>I read Modern C++ Design, I was first impressed (I still am). But then
>I began to think: Why should it be so hard to express something as
>useful and natural as these concepts? In my opinion Loki is only
>scratching the surface of techniques that need much more language
>support. I am of the view that as much work as possible, should be left
>to the compiler implementor. And there are many many examples of things
>that can be done today, but that really shouldn't be done my
>programmers but by compiler implementors.

It is possible to do OOP in C but it is hard work because C provides
inadequate support. In the same way, it is possible to do
meta-programming in C++ but it is hard work because currently C++ does
not provide adequate support. What the work of people like Andrei shows
is the value of meta-programming. Now the question should be whether
this value is high enough to require direct support from the language.

Note that there are no problems that cannot be solved in assembler but
there are quite a few that we would not want to. When we think that an
enhancement of C++ must be targeted at programming problems we need to
understand that we should be considering both the ease of solving a
problem and the portability of the solution.


--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

James Dennett

unread,
May 10, 2002, 5:04:46 PM5/10/02
to
James Kuyper Jr. wrote:
> David Sachs wrote:
>
>>Here are some extensions that I would like to see in a future version of the
>>C++ language.
>
> ....
>
>>2) A way to use placement operator delete and operator delete[] for memory
>>allocated with a placement operator new.
>
>
> That issue doesn't come up; there's no such thing as "memory allocated
> with a placement operator new". That's what makes it a placement
> operator new - the memory has already been allocated by the time that
> you use the 'new' operator to construct an object in it.

I think last time this was discussed to death, we concluded
that "placement operator new" is ambiguous: to some it means the
trivial standard-supplied form which takes a void* and returns
the value it is given, while to others (also reasonably) it
means any form which has more arguments than just a std::size_t.
For the latter group, placement new may well allocate memory.

--
James Dennett <jden...@acm.org>

James Kuyper Jr.

unread,
May 11, 2002, 7:24:01 AM5/11/02
to
James Dennett wrote:
>
> James Kuyper Jr. wrote:
> > David Sachs wrote:
> >
> >>Here are some extensions that I would like to see in a future version of the
> >>C++ language.
> >
> > ....
> >
> >>2) A way to use placement operator delete and operator delete[] for memory
> >>allocated with a placement operator new.
> >
> >
> > That issue doesn't come up; there's no such thing as "memory allocated
> > with a placement operator new". That's what makes it a placement
> > operator new - the memory has already been allocated by the time that
> > you use the 'new' operator to construct an object in it.
>
> I think last time this was discussed to death, we concluded
> that "placement operator new" is ambiguous: to some it means the
> trivial standard-supplied form which takes a void* and returns
> the value it is given, while to others (also reasonably) it
> means any form which has more arguments than just a std::size_t.
> For the latter group, placement new may well allocate memory.

I don't believe that's ambigous; the standard quite clearly defines
placement new as including forms of overloading other than the one
supplied by the standard. I just wasn't thinking about that when I wrote
that paragraph.

Edward Diener

unread,
May 11, 2002, 7:10:50 PM5/11/02
to
"Eric Niebler" <eri...@microsoft.com> wrote in message
news:3cdb0a06$1...@news.microsoft.com...

Since I have run into situations which are the same as yours, I don't have a
solution but I have a proposal which will allow the use of string literals
in template classes. Instead of L"literal string" to signify wide character
literals and L'literal character' to signify a wide character literal, we
should add the notation:

<character-type>"literal string" and
<character-type>'literal character'

where character type will be any built-in language character type, of which
we currently have two, "char" and "wchar_t", but of which C++ may add more
in the future. Thus the notation can expand in the future to include other
character types in our string literals. This would solve your problem above
by allowing you to specify,

CharT digits [] = <CharT>"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

and you would have the correct type of string literal.

This same type of notation should be extended to numeric literals. So
instead of writing "46L" to signify a long integer literal value, we should
be allowed to write "<long>46" instead, and once again this would solve the
problem of class templates parameterized on numeric types having to
represent numeric literal values based on the type. Although of course I
recognize that class templates parameterized on numeric types are much less
common than those parameterized on character types, the notational concept
is just as easily adapted to numeric literal values. The proposal for
numeric types would similarly be allowing this notation:

<numeric type>numeric-literal-value

and could just as easily be extended to new futures numeric types and
numeric literal values.

I have chosen putting the type of the literal in front of the literal
because of the syntactical similarity to the C++ cast expressions (
dynamic_cast, static_cast etc.), but if others feel that this would
introduce parsing difficulties, putting the type in back of the literal
might be just as acceptable.

David Rasmussen

unread,
May 13, 2002, 12:22:16 AM5/13/02
to
Francis Glassborow wrote:
>
> It is possible to do OOP in C but it is hard work because C provides
> inadequate support. In the same way, it is possible to do
> meta-programming in C++ but it is hard work because currently C++ does
> not provide adequate support. What the work of people like Andrei shows

Exactly.

> is the value of meta-programming. Now the question should be whether
> this value is high enough to require direct support from the language.
>

Sure. I think the real question is: What is missing that makes this so
hard? I think it would be a bad idea to make changes to the language
that target just these cases. Instead, we could ask ourselves: What is
the most general extension to the language, that would allow to do
things of this _class_, and does it make sense to make this change. In
the case of meta-programming, I don't see why it shouldn't be easier to
do. There is a whole class of concepts and problems that naturally could
use this.

> Note that there are no problems that cannot be solved in assembler but
> there are quite a few that we would not want to. When we think that an

Exactly. Ideally, C++ should allow/provide everything a programmer
wants, as long as it doesn't violate the zero-overhead principle etc. I
often find myself thinking: Grrr, this idea is simple, but it is really
difficult to express in C++, or: This idea _could_ really be done in a
static no-overhead fashion, if the language had the features, but
instead, I have to settle with a more dynamic version, or resort to
simple typographical endavours such as copying and pasting etc.

> enhancement of C++ must be targeted at programming problems we need to
> understand that we should be considering both the ease of solving a
> problem and the portability of the solution.
>

Sure, but all of the things I am talking about are portable "front-end"
stuff, not detailed platform-dependant back-end stuff. The only thing
that will get more difficult, would be the writing of the compiler. As I
said, there is no reason why I should have to make forward declarations
or use a preprocessor. It is only there to make life easier for the
compiler implementor. These are just simple examples.

/David

Tom Puverle

unread,
May 13, 2002, 12:23:36 AM5/13/02
to
> > Let me suggest a different approach. Instead of asking about language
> > features, put together a list of problems that aren't easily solved in
> > the language as it exists today.

1) I didn't say I wanted to add any features. I asked about the features
"people would like to see" in C++0x, sort of a conversation starter.

> Bravo, Pete!
>
> It seems like people want to throw in the kitchen sink without figuring
out
> if we need one -- or if, perhaps, we can put one together with the
existing
> plumbing.

I agree completely. However, why should the plumber have to bend a metal
pipe when he could use a plastic one? Also there is only as much bending as
a pipe will take. And sometimes it is not possible at all.

Paul Mensonides

unread,
May 13, 2002, 12:24:15 AM5/13/02
to
"Edward Diener" <eldi...@earthlink.net> wrote in message
news:DlhD8.4159$Nt3.3...@newsread2.prod.itd.earthlink.net...

[snip]

> <character-type>"literal string" and
> <character-type>'literal character'

[snip]

> CharT digits [] = <CharT>"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

If you use a pointer (rather than an array), this might help:

--------------------

template<class T> inline T local_of(const char*, const wchar_t*);

template<> inline const char* local_of(const char* used, const wchar_t*) {
return used;
}

template<> inline const wchar_t* local_of(const char*, const wchar_t* used) {
return used;
}

#define LOCAL_OF(type, sz) local_of<type>(sz, L ## sz)

--------------------

This is what I ended up using. The problem is that you cannot initialize an
array this way, like you can with a normal string literal--thereby making it
non-modifiable.

e.g....

struct something { };

template<class T> inline std::basic_ostream<T>&
operator<<(std::basic_ostream<T>& os, something) {
return os << LOCAL_OF(T, "something");
}

Paul Mensonides

Garry Lancaster

unread,
May 13, 2002, 1:19:16 PM5/13/02
to
[snip discussion of making the result of type_info.name()
compiler independent]

John G. Harris:


> There may be extra considerations, depending on what is being wished
> for.
>
> - If the application is spread over thousands of computers do we want my
> mumble::Thing class and your mumble::Thing class in different computers
> to have different identifiers?

If the classes have the same name (and, although
this is jumping the gun a bit on whether namespaces
should be part of the name, assuming they are in
the same namespace) their type_info.name() should
be the same. If you wish to add a computer identifier
to the resulting string, there are plenty of ways of doing
this. In a serialized representation of an object model
you'd probably want a computer identifier zero or one
times rather than repeated as part of every class name.

> - What about the standard library? Does vector<int> always have the same
> identifier, or does it depend on whose library it comes from?

It should always have the same name I think. And
that name should probably be "std::vector<int>".

Kind regards

Garry Lancaster
Codemill Ltd
Visit our web site at http://www.codemill.net

---

Francis Glassborow

unread,
May 13, 2002, 1:19:05 PM5/13/02
to
In article <abf15l$8t2$1...@info1.fnal.gov>, David Sachs <sa...@fnal.gov>
writes

>2) A way to use placement operator delete and operator delete[] for memory
>allocated with a placement operator new.

That is much harder than it seems. First off, it would necessary to
track how dynamic objects have been created (the only case that that is
currently required is during construction which is relatively
inexpensive)

--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

Garry Lancaster

unread,
May 13, 2002, 1:19:52 PM5/13/02
to
Pete Becker:

> > Let me suggest a different approach. Instead of asking
> > about language features, put together a list of problems
> > that aren't easily solved in the language as it exists today.

Scott Robert Ladd:


> Bravo, Pete!
>
> It seems like people want to throw in the kitchen sink
> without figuring out if we need one -- or if, perhaps,
> we can put one together with the existing plumbing.

Just because we don't see the problem-related
groundwork in a particular discussion of a feature,
doesn't mean it never happened elsewhere.

When suggesting a new feature giving a brief
recap of the rationale would, even if nothing else,
make the thread more accessible to those who
haven't seen previous relevant discussions.

I also think there's something to be said for
dreaming out loud about features even if they
don't have immediately obvious applications.
As long as the two ends meet up eventually it
doesn't really matter in which order they were
first thought of.

Kind regards

Garry Lancaster
Codemill Ltd
Visit our web site at http://www.codemill.net

---

kgw-zamb...@stiscan-zamboni.com

unread,
May 13, 2002, 1:20:31 PM5/13/02
to
On Fri, 10 May 2002 08:35:10 UTC, "Eric Niebler" <eri...@microsoft.com> wrote: WEEKDAY

I have concluded long ago that constants should be of universal
type.
I should be able to write:
int I = 123456789;
long L = 123456789;
short S = 123456789;
char c = 'a';
wchar_t = 'a';
float f = 123456789.987654321;
double d = 123456789.987654321;

without needing to specify to the compiler the type of the constant.
Constants start out at the maximum precision and only produce
an error/warning if truncation actually happens at compile time.
Only if the programmer gives a specific type suffix is it forced to
a lesser type.
All string/character constants should start out in full UNICODE
and be implicitly converted to the desired target type at compile time.

>Thanks,
>Eric
>
>
>
>---
>[ comp.std.c++ is moderated. To submit articles, try just posting with ]
>[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
>[ --- Please see the FAQ before posting. --- ]
>[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
>


--
ÿ
ÿ
Remove -zamboni to reply
All the above is hearsay and the opinion of no one in particular

Francis Glassborow

unread,
May 13, 2002, 1:21:15 PM5/13/02
to
In article <cinmdukfbf408nnol...@4ax.com>, Steve Heller
<st...@steveheller.com> writes

> I would like the standard to guarantee that deleting a derived class
>object through a base class pointer will work even if the destructor
>is not virtual, so long as the derived class adds no data members.

Sorry, but in the context of multiple inheritance and virtual bases that
does not work. (It is possible to change the layout of a class without
adding data:

struct X {
virtual ~X();

// whatever
};

struct Y {

// whatever
};

struct Z {
// whatever
};

struct A: public Y, virtual public X{

// whatever
};

struct B: public Z {
// whatever
};


struct C: public A, public B {
// whatever
};


Now I believe that in many compilers:

struct D: virtual public X, public C {
};

Has the same semantics as C but will have a different layout so you
better not delete either C or D through Y* or Z* variables.

--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

Steve Clamage

unread,
May 13, 2002, 1:22:43 PM5/13/02
to
On Fri, 10 May 2002, Steve Heller wrote:
>
> I would like the standard to guarantee that deleting a derived class
> object through a base class pointer will work even if the destructor
> is not virtual, so long as the derived class adds no data members.

file Base.h:
---------------
class Base { };


file Derived.h:
-----------------
void foo(); // function foo has a user-visible effect

class Derived : public Base {
public:
~Derived() { foo(); }
];


file bar.cc:
--------------
#include "Base.h"

void bar(Base* bp) { delete bp; }


If Base does not have a virtual destructor, and you pass a Derived*
to bar, what mechanism do you propose for the Derived destructor
to be called?

--
Steve Clamage, stephen...@sun.com

Hyman Rosen

unread,
May 13, 2002, 1:22:22 PM5/13/02
to
Francis Glassborow wrote:
> This is part of the more extensive problem of providing full support for
> literals which is one of the problems that the evolution workgroup has
> already identified as needing consideration.

As usual, you may want to look at Ada, which has already neatly
solved the problem. In Ada, literals of an enumeration type can
be character literals (and you can mix regular and character
literals in the same type) of the form 'x'. String literals are
arrays of the corresponding character literals. The types of
these literals are determined from context, so the literals
don't need any weird prefixes to distinguish between character,
wide character, or user-defined character tpes.

See <http://adahome.com/rm95/rm9x-03-05-02.html>.

Joe Gottman

unread,
May 13, 2002, 1:27:26 PM5/13/02
to
"Pete Becker" <peteb...@acm.org> wrote in message
news:3CDA7DBA...@acm.org...
> Instead of asking about language
> features, put together a list of problems that aren't easily solved in
> the language as it exists today.

Two things come to mind:

1) We need typeof() so that we can declare variables whose type is some
function of one or more other variables. For instance, suppose you had a
template class polynomial<X>. If you wanted to declare a function to return
the sum of two polynomials of different types, the return type would have to
be something like polynomial<typeof(X() + Y())>. There's no good way to do
this now without manually defining and maintaining some sort of traits
class, which is clumsy and error-prone.

2) If a class contains an STL container of some sort, it is likely to
have several pairs of functions looking like the following:
iterator foo() { // some code}
const_iterator foo() const {// the same code as above }

For maintainability, it would be nice if it were possible to define one of
these functions in terms of the other, but currently it is impossible. The
const version cannot call the non-const version because const functions can
only call other const functions. The non-const version cannot call the
const version because it generally is not possible to convert a
const_iterator to a plain iterator.

Joe Gottman

John Nagle

unread,
May 13, 2002, 1:34:34 PM5/13/02
to
Scott Robert Ladd wrote:

> "Pete Becker" <peteb...@acm.org> wrote in message
> news:3CDA7DBA...@acm.org...
>
>>Let me suggest a different approach. Instead of asking about language
>>features, put together a list of problems that aren't easily solved in
>>the language as it exists today.


OK.

Memory/pointer safety, or lack thereof - the big one.
Cause of more bugs than all the other problems put together.
Yes, I know all the usual arguments. But as C# and Java
gain market share, C++ can't ignore this problem any more.

Concurrency - the language needs to know about threads
and locking. Maybe it doesn't need to know much, but ignoring
the problem doesn't make it go away.

Marshalling - it's hard to hook up C++ to any of the
many marshalled calling conventions (DCOM/CORBA/RMI/.NET/etc.)
without a stub generator or too much manual work.

The "include" approach to interfaces fosters too
much unwanted interdependency in large projects. Changing
the private part of a class forces a recompile of the
class's users. On large projects, this generates
huge amounts of irrelevant recompile activity, and then
trying to avoid those recompiles warps designs out of shape.

It's possible to fix all these problems without going
to an interpretive environment like .NET or Java. Is
the C++ community up to the job?

John Nagle
Animats

James Kanze

unread,
May 13, 2002, 1:35:02 PM5/13/02
to
Steve Heller <st...@steveheller.com> writes:

|> I would like the standard to guarantee that deleting a derived
|> class object through a base class pointer will work even if the
|> destructor is not virtual, so long as the derived class adds no
|> data members.

And what if the derived class has virtual functions, and the base
class not? Or if the derived class derives from two base classes? Or
virtual inheritance?

The question isn't simple. I'd also like to see something along the
lines of "trivial inheritance", which would allow an array of Derived
to work like an array of Base. But I recognize that defining "trivial
inheritance" isn't trivial, and I don't know if the effort is really
worth the gain.

--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

Edward Diener

unread,
May 13, 2002, 1:37:15 PM5/13/02
to
"Paul Mensonides" <pmen...@attbi.com> wrote in message
news:shjD8.13429$1B....@rwcrnsc51.ops.asp.att.net...

> "Edward Diener" <eldi...@earthlink.net> wrote in message
> news:DlhD8.4159$Nt3.3...@newsread2.prod.itd.earthlink.net...
>
> [snip]
>
> > <character-type>"literal string" and
> > <character-type>'literal character'
>
> [snip]
>
> > CharT digits [] = <CharT>"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
>
> If you use a pointer (rather than an array), this might help:

Something like ?::

CharT * digits = <CharT>"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

However one is allowed to write:

char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

or

wchar_t digits[] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

I was just illustrating my proposal, using the original example which Eric
Niebler presented, for extending the literal types to use templated syntax,
ie. <type>literal, so that they can be used more easily in template classes
and functions.

> --------------------
>
> template<class T> inline T local_of(const char*, const wchar_t*);
>
> template<> inline const char* local_of(const char* used, const wchar_t*) {
> return used;
> }
>
> template<> inline const wchar_t* local_of(const char*, const wchar_t*
used) {
> return used;
> }
>
> #define LOCAL_OF(type, sz) local_of<type>(sz, L ## sz)
>
> --------------------
>
> This is what I ended up using. The problem is that you cannot initialize
an
> array this way, like you can with a normal string literal--thereby making
it
> non-modifiable.

Yes, it has that limitation.

>
> e.g....
>
> struct something { };
>
> template<class T> inline std::basic_ostream<T>&
> operator<<(std::basic_ostream<T>& os, something) {
> return os << LOCAL_OF(T, "something");
> }

Yes, a neat solution.

Of course if more character types are added to the language and your
template function accepts another one, then you have to change your
solution. Whereas my proposal for a syntax change would take care of that at
the compiler level.

template<class T> inline std::basic_ostream<T>&
operator<<(std::basic_ostream<T>& os, something) {

return os << <T>"something";

Of course this doesn't presently exist but illustrates my proposal.

Fergus Henderson

unread,
May 13, 2002, 1:45:24 PM5/13/02
to
David Rasmussen <david.r...@gmx.spam.egg.sausage.and.spam.net> writes:

>Making a language better is not always about adding normal language
>features. One of the things I would like very much in C++, that is
>impossible now, is to be able to disable a language feature. That is, I
>would like to be able to state somehow in my program, that old-style
>casts are not allowed.

FWIW, there is some prior art for this in Ada.
Ada 95 has a `pragma Restrictions' declaration for this,
with a large number of standard restrictions, e.g. `No_Exceptions',
`No_Floating_Point', `No_Recursion', `No_IO', `No_Unchecked_Conversion',
etc.

See sections 13.12, H.4, and D.7 in the Ada Reference Manual for details.

--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.

Hyman Rosen

unread,
May 13, 2002, 3:28:32 PM5/13/02
to
Steve Clamage wrote:
> If Base does not have a virtual destructor, and you pass a Derived*
> to bar, what mechanism do you propose for the Derived destructor
> to be called?

None. He wants this to act just like deleting an actual Base
object, and not have undefined behavior. It's an unworkable
proposal for a number of reasons.

Tom Puverle

unread,
May 13, 2002, 4:08:07 PM5/13/02
to
> When suggesting a new feature giving a brief
> recap of the rationale would, even if nothing else,
> make the thread more accessible to those who
> haven't seen previous relevant discussions.
>
> I also think there's something to be said for
> dreaming out loud about features even if they
> don't have immediately obvious applications.
> As long as the two ends meet up eventually it
> doesn't really matter in which order they were
> first thought of.

That is exactly the reason why I started the thread:

- I was trying to find out if anyone had any insider info on
any of the new proposals/additions
- wanted to learn what other "unsolved/unsolvable" C++ problems there
are.
(because I always enjoy trying to come up with a solution with the
current language
features)

Anyway, all the things that were mentioned in the original post are being
considered
by the C++ committee, AFAIK. (Btw. is there a complete summary of proposed
extensions
anywhere on the net? I know about the papers on WG11 website btw... )

Since we are in the middle of feature creep, why not carry on: Here's a
feature and a rationale:

Allow specialisation of member templates without specialising the outer
template first.

Here's an example:
Remember Andrei's book and the Conversion<> template? He says he finds it
difficult
to remember which way the conversion is going, and hence the SUPERSUBCLASS
macro.
Now imagine this:

template<typename T>
struct ConversionFrom
{
template<typename U>
struct To
{
//..ConversionHelper stuff...
static const bool exists = //conversion Helper stuff...
static const bool exists2Way = exists && ConversionFrom<U>::template
To<T>::exists;
static const bool sameType = false;
};
};

Now I could write:
ConversionFrom<Type1>::To<Type2>::exists
IMHO this is more readable and has also the added advantage of being
namespace scoped (unlike macros)

if only I could do this:

template<>
template<class T>
struct ConversionFrom<T>::To<T>
{
exists = true;
static const bool exists2Way = true;
static const bool sameType = true;

};

Now I could use partial specialisation on To<> but why should something so
simple be
so "complicated" to do?
This can be resolved by having a SameType<> template with two parameters...

Some other things (apart from the ones I already mentioned):
- Why not allow forward declarations of inner classes/classes in
namespaces? There isn't a way to
do the first and it is extremely irritating having to reopen a
namespace (especially if it is nested)
just to create a forward declaration.

These are a few of my gripes.

Tom

Howard Gardner

unread,
May 14, 2002, 1:53:38 PM5/14/02
to
Pete Becker wrote:
> Tom Puverle wrote:
>
>>I am trying to put together a wish list of language extensions that people
>>would like to see in C++0x.

>
>
> Let me suggest a different approach. Instead of asking about language
> features, put together a list of problems that aren't easily solved in
> the language as it exists today. Language features aren't an end in
> themselves, but are a way of solving problems. Focusing initially on
> problems rather than solutions will lead to a better set of solutions.
>

Ok, here's one.

Publicly deriving from std::string risks a delete through a base class
pointer, and so it risks undefined behavior and is a nono. Same is true
for the containers.

I've seen arguments for and against subclassing those things at all, and
I've seen arguments for and against adding virtual destructors to them
in order to support the subclassing. What I haven't seen is a proposal
to end the argument.

It seems to me that this should do the trick. In fact, it's so glaringly
obvious that I wonder if I just missed the discussion.

struct no_virtual_destructor{};

struct virtual_destructor{ virtual ~virtual_destructor(){} };

template<..., class destructor_policy = no_virtual_destructor>
class basic_string : public destructor_policy {...};

The default case is unchanged, so it shouldn't break anything.

Someone who wants to subclass it can just change the destructor policy
and be on their merry way.

It will also let people who want to "abuse" the mechanism and make other
functions virtual.

It doesn't change the argument about subclassing at all, but it sure
makes it less interesting.

--
I <3 Comeau C++: http://www.comeaucomputing.com

Tom Puverle

unread,
May 14, 2002, 1:56:15 PM5/14/02
to
[ Moderator - this was sent to my private address, I expect the sender
replied to me rather than the group by accident. Could you put it on the
newsgroup under his name please ]

> -----Original Message-----
> From: Felix Shvaiger [mailto:fshv...@cisco.com]
> Sent: 14 May 2002 09:28
> To: Tom Puverle
> Subject: Re: C++0x Wish list
]

Wish 1:
Some keyword like 'noinherit' which mean,
that virtual method could not be inherited by
derived class, but rather must be overrided
in each direct or undirect derived class.
This will persuade the author of derived class
to do not forget to override such method every time.
Example:
class ClassUID;
class BaseClass {
public:
virtual noinherit ClassUID get_class_uid ();
};
class DerivedClass1 :public BaseClass {
public:
ClassUID get_class_uid ();
};
class DerivedClass2 :public BaseClass {
public:
int a;
};
class DerivedClass3 :public BaseClass {
public:
ClassUID get_class_uid ();
};
BaseClass v; /* OK */
DerivedClass1 v1; /* OK */
DerivedClass2 v2; /* Compilation Error: method "ClassUID get_class_uid
()" must be defined in DerivedClass2 in order to instantiate it (like
abstract method) */
DerivedClass3 v3; /* OK */

Ken Hagan

unread,
May 14, 2002, 6:26:25 PM5/14/02
to
"John Nagle" <na...@animats.com> wrote...

>
> Marshalling - it's hard to hook up C++ to any of the
> many marshalled calling conventions (DCOM/CORBA/RMI/.NET/etc.)
> without a stub generator or too much manual work.

I wouldn't want to invent "yet another IDL" and require it to be
built into every C++ compiler. On the other hand, it might be
possible permit custom attributes that the compiler ignores but
which another compiler (for your favourite IDL) uses.

Ideally, the C++ compiler would perform the task of "parsing out"
all the difficult C++ syntax, leaving only the declarations needed
to pass on all the attributes. This would simplify the "other"
compiler, perhaps to the point at which existing implementations
could be used. We'd probably need some way of "quoting" text that
isn't a declaration, so that things like tool-specific pragmas
could be included as well.

This isn't very different from how such tools are used today. The
basic problem is how to maintain two sets of declarations that have
to be consistent. The two languages in question, C++ and IDL, are
broadly similar and IDL minus its attributes is almost a subset.

Today I write IDL and try to auto-generate C++, the richer language.
This inevitably leads to loads of "C++ markup" in my IDL, and in
fact I've found it impossible to persuade MIDL (Microsoft's IDL
compiler to generate clean C++ with inline helpers, proper use of
const and the convenience of overloaded names, so I'm reduced to
using the preprocessor and maintaining parallel sets of declarations.
(Either that or I could compromise on my use of C++, but hey, we
don't need yet another reason to avoid all those nice C++ features.)

In future, I'd like to write C++ and auto-generate IDL, a near-
subset. My belief (hope) is that the conversion from C++ to IDL is
mostly a matter of stripping out stuff, rather than transforming.

Example:

typedef wchar_t const* LPCOLESTR;
struct "[attribs]" MailRules
{
long Add2Killfile("[in,string]" LPCOLESTR s);
long IsInKillfile("[in,string]" LPCOLESTR s) const;
};

The compiler would generate the usual code output, but also spit out
a post-processed file containing...

typedef wchar_t const* LPCOLESTR;
struct [attribs] MailRules
{
long Add2Killfile([in,string] LPCOLESTR s);
long IsInKillfile([in,string] LPCOLESTR s) const;
};

Notice that LPCOLESTR is emitted as well, since it is used by MailRules,
even though it carries no attributes.

I dare say my proposed syntax is unworkably cute, but something like
__idl("[attribs]") would probably work, and __idl("[attribs]",tag)
with different values for "tag" could generate files for several other
tools, not just one. Both of these could be hidden by brutal macros
for those with delicate fingers and strong stomachs.

#define IN __idl("[in]")
#define STRING __idl("[string]")
...
typedef STRING wchar_t const* LPCOLESTR;
long IsInKillfile(IN LPCOLESTR s) const;

Steve Heller

unread,
May 14, 2002, 6:43:23 PM5/14/02
to
Francis Glassborow <francis.g...@ntlworld.com> wrote:

Ok, then how about this:

"If the derived class does not add any data members, and does not have
multiple base classes, then deletion through the base class pointer
will delete the base class part properly"

or words to that effect?

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

John Nagle

unread,
May 15, 2002, 12:42:31 PM5/15/02
to
Ken Hagan wrote:

> "John Nagle" <na...@animats.com> wrote...
>
>> Marshalling - it's hard to hook up C++ to any of the
>>many marshalled calling conventions (DCOM/CORBA/RMI/.NET/etc.)
>>without a stub generator or too much manual work.
>>
>
> I wouldn't want to invent "yet another IDL" and require it to be
> built into every C++ compiler. On the other hand, it might be
> possible permit custom attributes that the compiler ignores but
> which another compiler (for your favourite IDL) uses.


I was thinking more in terms of "introspection", the ability
of a class to enumerate its own members. Suppose there was
a built-in function that returned something like an array of
typeinfo for all the data members of a class. And
one which attempted to apply a specified template function to member
N, with all the necessary checking at compile time. Then you
could just derive your class from some class that supported
the marshalling operations, and get a "dump as string",
"dump as XML", or "dump as CORBA params" generated.

That way, C++ doesn't have to understand the marshalling
mechanism.

John Nagle
Animats

John Nagle

unread,
May 15, 2002, 1:33:29 PM5/15/02
to
>>From: Felix Shvaiger [mailto:fshv...@cisco.com]
>>Sent: 14 May 2002 09:28
>>To: Tom Puverle
>>Subject: Re: C++0x Wish list

> Some keyword like 'noinherit' which mean,


> that virtual method could not be inherited by
> derived class, but rather must be overrided
> in each direct or undirect derived class.


I'm not entirely sure what that means.

I suggest simply prohibiting the overriding of non-virtual functions.
That would seem to provide the functionality requested. It's almost
always an error when someone overrides a non-virtual function.
On the rare occasions that you really want to do that, you can
use a different function name.

John Nagle

John G Harris

unread,
May 15, 2002, 1:42:47 PM5/15/02
to
In article <aRNC8.11900$xb4.1...@news6-win.server.ntlworld.com>,
Garry Lancaster <glanc...@ntlworld.com> writes

>[snip discussion of making the result of type_info.name()
>compiler independent]
>
>John G. Harris:
>> There may be extra considerations, depending on what is being wished
>> for.
>>
>> - If the application is spread over thousands of computers do we want my
>> mumble::Thing class and your mumble::Thing class in different computers
>> to have different identifiers?
>
>If the classes have the same name (and, although
>this is jumping the gun a bit on whether namespaces
>should be part of the name, assuming they are in
>the same namespace) their type_info.name() should
>be the same. If you wish to add a computer identifier
>to the resulting string, there are plenty of ways of doing
>this. In a serialized representation of an object model
>you'd probably want a computer identifier zero or one
>times rather than repeated as part of every class name.
<snip>

If having the same identifier doesn't guarantee that interworking is
possible then I don't understand why an ISO-defined identifier would
benefit anyone.

John
--
John Harris
mailto:jo...@jgharris.demon.co.uk

Steve Heller

unread,
May 15, 2002, 1:47:03 PM5/15/02
to
Howard Gardner <use...@hgardner.com> wrote:

I'll go for this solution, assuming I understand it. Can you give an
example where the "virtual_destructor" struct is used?

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---

James Kanze

unread,
May 15, 2002, 1:53:12 PM5/15/02
to
Steve Heller <st...@steveheller.com> writes:

|> >Has the same semantics as C but will have a different layout so
|> >you better not delete either C or D through Y* or Z* variables.

|> Ok, then how about this:

|> "If the derived class does not add any data members, and does not
|> have multiple base classes, then deletion through the base class
|> pointer will delete the base class part properly"

A safer solution would be to list what the derived class *can* do and
still have the guarantee. If you forget something, it is trivial to
add it later, whereas you generally can't add restrictions once you've
allowed something.

Off-hand, I'd start with only allowing non-virtual member functions,
although 1) things like typedef's, enum etc. certainly shouldn't pose
a problem, and 2) nor should new static members.

Anyhow, as I've said, I think it is doable, but I'm not convinced that
it is worth it. What I'd suggest is that you write up some sort of a
proposal just allowing additional non-virtual member functions and
single, non-virtual inheritance, but with a very good rationale
section -- why this is needed. If the rationale is convincing, we can
think about what else can be allowed, but discussing the details
before having convinced people that the extension is in any way useful
is not particularly productive.

(I know you think it is useful, but I'm not sure you've convinced
anyone else yet. I think that it could be slightly useful, but not
useful enought to warrent additional special cases which have to be
taught -- the language is complicated enough as is.)

--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---

Paul Mensonides

unread,
May 15, 2002, 1:56:47 PM5/15/02
to
"Edward Diener" <eldi...@earthlink.net> wrote in message
news:INSD8.7768$Nt3.6...@newsread2.prod.itd.earthlink.net...

> > struct something { };
> >
> > template<class T> inline std::basic_ostream<T>&
> > operator<<(std::basic_ostream<T>& os, something) {
> > return os << LOCAL_OF(T, "something");
> > }
>
> Yes, a neat solution.
>
> Of course if more character types are added to the language and your
> template function accepts another one, then you have to change your
> solution. Whereas my proposal for a syntax change would take care of that at
> the compiler level.
>
> template<class T> inline std::basic_ostream<T>&
> operator<<(std::basic_ostream<T>& os, something) {
> return os << <T>"something";
>
> Of course this doesn't presently exist but illustrates my proposal.

I would rather have it at a language level also, however I don't really like the
use of angle-brackets at the beginning of an expression. Of course, that is not
a serious issue.

Paul Mensonides

Fergus Henderson

unread,
May 15, 2002, 1:57:43 PM5/15/02
to
Francis Glassborow <francis.g...@ntlworld.com> writes:

>David Sachs <sa...@fnal.gov> writes
>>2) A way to use placement operator delete and operator delete[] for memory
>>allocated with a placement operator new.
>
>That is much harder than it seems. First off, it would necessary to
>track how dynamic objects have been created (the only case that that is
>currently required is during construction which is relatively
>inexpensive)

I don't understand your objection here. Could you elaborate?

Do you mean that the compiler would need to track this, or the user?
If the former, why? If the latter, why would this be a problem?

--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.

---

Felix Shvaiger

unread,
May 15, 2002, 1:58:30 PM5/15/02
to
Wish 2:
Static virtual methods.
Now I implement this some way like:

class SomeClassProperty;

class BaseClass {
public:
static SomeClassProperty staticGetSomeClassProperty ();
virtual SomeClassProperty virtualGetSomeClassProperty () {
return staticGetSomeClassProperty ();
};
};

class DerivedClass :public BaseClass {
public:
static SomeClassProperty staticGetSomeClassProperty ();
SomeClassProperty virtualGetSomeClassProperty () {
return staticGetSomeClassProperty ();
};
};

This is only one example, there are others.
But I do not understand, why is it problem to keep pointer to
static function in virtual method table.
I can't just move implementation of static method to virtual method
or remove virtual method because in some place I want

prop = ptr->virtualGetSomeClassProperty (); /* we have instance and want to
get its exact class's property */

and some other place:

prop = MyClass::staticGetSomeClassProperty (); /* we have no instance */

Why can't I write

class BaseClass {
public:
static virtual ();
};

class DerivedClass :public BaseClass {
public:
getSomeClassProperty (); /* note: 'static' behavior is 'inherited' from
BaseClass::getSomeClassProperty() like 'virtual' behavior */
};

When called via pointer such function will be found in virtual method table,
but will be called without 'this' pointer.

What do You say ?


==============
Felix Shvaiger
fshv...@cisco.com

Dave Harris

unread,
May 15, 2002, 1:59:29 PM5/15/02
to
use...@hgardner.com (Howard Gardner) wrote (abridged):

> Publicly deriving from std::string risks a delete through a base class
> pointer, and so it risks undefined behavior and is a nono. Same is true
> for the containers.

I think there's more to it than just deletion.

For example, I have found myself wanting an "owning vector", which holds
pointers and deletes them when they are erased. In order to guarantee my
semantics, I have to catch every function which does erasure - off the top
of my head that's erase() (2 versions), clear() and the destructor. Having
a virtual destructor doesn't help me unless erase() and clear() are also
virtual (or the 2-argument erase() is virtual and the others are defined
in terms of it).

I would rather see ways to make private inheritance, and/or delegation,
safer and easier to use. For example, a using-declaration which can select
just the const version of begin() and end(). Or contrariwise, a
using-declaration which can select the entire base class public interface.
A way of inheriting constructors would be nice, too. A better forwarding
mechanism.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

Alex Oren

unread,
May 15, 2002, 1:59:37 PM5/15/02
to
On Thu, 9 May 2002 16:55:33 GMT, Pete Becker wrote in
<3CDA7DBA...@acm.org>:

> Tom Puverle wrote:
> >
> > I am trying to put together a wish list of language extensions that people
> > would like to see in C++0x.
>
> Let me suggest a different approach. Instead of asking about language
> features, put together a list of problems that aren't easily solved in
> the language as it exists today. Language features aren't an end in
> themselves, but are a way of solving problems. Focusing initially on
> problems rather than solutions will lead to a better set of solutions.

There is something that, admittedly, can be easily solved but the
solution is very inelegant (IMHO).

Several standard library algorithms require functions (or functors) as
arguments. A separate, single-use function or functor to be used in
such an algorithm makes the code more cumbersome, less readable and less
maintainable (again, IMHO).

While adding full-blown lambda functions to C++ is probably not going to
happen (I can think of persistence issues), some kind of restricted
"lambda light" can be useful.

Consider the following trivial example (modulo syntax):

struct Item { int i; }
std::vector<Item> a;
// ...

std::sort(a.begin(),
a.end(),
bool (const Item& a, const Item& b) { return a.i > b.i; });

Hey, could be an opportunity to overload the "auto" keyword...


Best regards,
Alex.

--
To email me, replace "myrealbox" with "alexoren".
Sorry for the inconvenience. Blame the spammers.

Howard Gardner

unread,
May 15, 2002, 2:19:49 PM5/15/02
to
Steve Heller wrote:

> Howard Gardner <use...@hgardner.com> wrote:
>
>>struct no_virtual_destructor{};
>>
>>struct virtual_destructor{ virtual ~virtual_destructor(){} };
>>
>>template<..., class destructor_policy = no_virtual_destructor>
>> class basic_string : public destructor_policy {...};
>>
>>The default case is unchanged, so it shouldn't break anything.
>>
>>Someone who wants to subclass it can just change the destructor policy
>>and be on their merry way.
>>
>>It will also let people who want to "abuse" the mechanism and make other
>>functions virtual.
>>
>>It doesn't change the argument about subclassing at all, but it sure
>>makes it less interesting.
>
>
> I'll go for this solution, assuming I understand it. Can you give an
> example where the "virtual_destructor" struct is used?
>

Yes, there's one in Steve Heller's upcoming book, in the section titled
"Extending the functionality of strings." ;)

It would allow this to work without the potential for violation of LSP
or undefined behavior:

class xstring : public basic_string <..., virtual_destructor> {...};

The full behavior of basic string is inherited safely.

--
I <3 Comeau C++: http://www.comeaucomputing.com

---

Garry Lancaster

unread,
May 15, 2002, 2:53:38 PM5/15/02
to
John G. Harris:

> If having the same identifier doesn't guarantee that interworking is
> possible then I don't understand why an ISO-defined identifier would
> benefit anyone.

I'm not sure what you mean by that. You need much
more than consistent type names for portable
code and producing portable serialised objects, but
it's one step in the right direction.

Kind regards

Garry Lancaster
Codemill Ltd
Visit our web site at http://www.codemill.net

Howard Gardner

unread,
May 15, 2002, 2:57:04 PM5/15/02
to
Dave Harris wrote:
> use...@hgardner.com (Howard Gardner) wrote (abridged):
>
>>Publicly deriving from std::string risks a delete through a base class
>>pointer, and so it risks undefined behavior and is a nono. Same is true
>>for the containers.
>
>
> I think there's more to it than just deletion.

Yes there is. There's an ongoing argument. I think that there are valid
points on both sides.

> For example, I have found myself wanting an "owning vector", which holds
> pointers and deletes them when they are erased. In order to guarantee my
> semantics, I have to catch every function which does erasure - off the top
> of my head that's erase() (2 versions), clear() and the destructor. Having
> a virtual destructor doesn't help me unless erase() and clear() are also
> virtual (or the 2-argument erase() is virtual and the others are defined
> in terms of it).

The solution that I proposed would, in fact, let you make those
functions virtual:

template <...>
struct virtualize_erase
{
virtual ... erase (...);
virtual ... erase (...);
virtual ... clear (...);
virtual ~virtualize_erase();
};

class my_string
: public basic_string <..., virtualize_erase<...>>
{...};

As long as the signatures of the functions match, the functions in
basic_string will become virtual.

This may be a bad thing because it might make implementations of
std::basic_string harder. I've implemented templates that work like
this. It can be a scary world when the question "Is this function
virtual?" has for an answer "I don't know." Even where it does no harm
it changes the appropriate mindset for code inspection. It's like
exception handling in that regard, though not quite so perilous.

Andrei Alexandrescu's policies have the same strength/weakness:
inheriting from a template parameter allows users to "virtualize" any
function(s) they choose. It seems to me that exercising that power would
violate the spirit of the thing. I'm reading his book now, but I haven't
encountered a discussion of the topic yet.

There's a pretty clean solution to your particular need that doesn't
involve virtual functions at all. I haven't tested this implementation,
but I have used similar code many times:

template <class Object>
class deep_pointer
{
public:
deep_pointer(const Object & f_object = Object())
: m_ptr( new Object(f_object) )
{
}

deep_pointer(const deep_pointer & f_deep_pointer)
: m_ptr( new Object( *(f_deep_pointer.m_ptr) ) )
{
}

deep_pointer & operator = (const deep_pointer & f_deep_pointer)
{
Object * f_ptr = new Object( *(f_deep_pointer.m_ptr) );
delete m_ptr;
m_ptr = f_ptr;
return *this;
}

~deep_pointer()
{
delete m_ptr;
}

// whatever interface you want to give it for accessing the
// indicated Object.
private:
Object * m_ptr;
};

>
> I would rather see ways to make private inheritance, and/or delegation,
> safer and easier to use. For example, a using-declaration which can select
> just the const version of begin() and end(). Or contrariwise, a
> using-declaration which can select the entire base class public interface.
> A way of inheriting constructors would be nice, too. A better forwarding
> mechanism.

A better forwarding mechanism might be useful, but it's not actually
necessary to solve this particular problem.

--
I <3 Comeau C++: http://www.comeaucomputing.com

---

Francis Glassborow

unread,
May 15, 2002, 4:07:12 PM5/15/02
to
In article <abpv7d$sr7$1...@mulga.cs.mu.OZ.AU>, Fergus Henderson
<f...@cs.mu.OZ.AU> writes

>Francis Glassborow <francis.g...@ntlworld.com> writes:
>
>>David Sachs <sa...@fnal.gov> writes
>>>2) A way to use placement operator delete and operator delete[] for memory
>>>allocated with a placement operator new.
>>
>>That is much harder than it seems. First off, it would necessary to
>>track how dynamic objects have been created (the only case that that is
>>currently required is during construction which is relatively
>>inexpensive)
>
>I don't understand your objection here. Could you elaborate?
>
>Do you mean that the compiler would need to track this, or the user?
>If the former, why? If the latter, why would this be a problem?

Sorry, I was thinking of something else (distracted by the thread on
overloaded dtors)


--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Dave Harris

unread,
May 15, 2002, 6:41:44 PM5/15/02
to
na...@animats.com (John Nagle) wrote (abridged):

> I suggest simply prohibiting the overriding of non-virtual
> functions.

Unless they are private. I don't think there's anything wrong with
overriding a private non-virtual, and indeed this is a necessary
facility. Otherwise base classes become even more fragile than they
already are.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

---

Edward Diener

unread,
May 15, 2002, 6:56:42 PM5/15/02
to
"Paul Mensonides" <pmen...@attbi.com> wrote in message
news:Y8XD8.508$Bw6...@rwcrnsc51.ops.asp.att.net...

> "Edward Diener" <eldi...@earthlink.net> wrote in message
> news:INSD8.7768$Nt3.6...@newsread2.prod.itd.earthlink.net...
> > > struct something { };
> > >
> > > template<class T> inline std::basic_ostream<T>&
> > > operator<<(std::basic_ostream<T>& os, something) {
> > > return os << LOCAL_OF(T, "something");
> > > }
> >
> > Yes, a neat solution.
> >
> > Of course if more character types are added to the language and your
> > template function accepts another one, then you have to change your
> > solution. Whereas my proposal for a syntax change would take care of
that at
> > the compiler level.
> >
> > template<class T> inline std::basic_ostream<T>&
> > operator<<(std::basic_ostream<T>& os, something) {
> > return os << <T>"something";
> >
> > Of course this doesn't presently exist but illustrates my proposal.
>
> I would rather have it at a language level also, however I don't really
like the
> use of angle-brackets at the beginning of an expression. Of course, that
is not
> a serious issue.

I choose the angle brackets for two reasons:

1) "<type>literal" does not seem, at first thought, as something that can be
used in any other situation and I want the parser for a C++ compiler
implementation to be able to pick it up easily.
2) It mimics the C++ casting operations and I see my solution as sort of a
cast. Of course I am not really casting a literal to another type, but just
telling the compiler to treat my literal as a specific type, but the concept
of specifying a type is similar.

Of course in order to not break existing code, the current methods of
specifying literals of various types should still be supported, so I see my
proposal as an addition and not a replacement. Obviously the addition makes
using literals in templated functions and classes easier.

I agree the exact syntax for this idea is not a serious issue and I would
defer to another syntax which would make it easy to specify and which would
cause the C++ compiler parser few problems. But I do like my syntax for the
reasons above.

Steve Heller

unread,
May 16, 2002, 4:16:15 AM5/16/02
to
James Kanze <ka...@alex.gabi-soft.de> wrote:

>Steve Heller <st...@steveheller.com> writes:
>
>|> >Has the same semantics as C but will have a different layout so
>|> >you better not delete either C or D through Y* or Z* variables.
>
>|> Ok, then how about this:
>
>|> "If the derived class does not add any data members, and does not
>|> have multiple base classes, then deletion through the base class
>|> pointer will delete the base class part properly"
>
>A safer solution would be to list what the derived class *can* do and
>still have the guarantee. If you forget something, it is trivial to
>add it later, whereas you generally can't add restrictions once you've
>allowed something.
>
>Off-hand, I'd start with only allowing non-virtual member functions,
>although 1) things like typedef's, enum etc. certainly shouldn't pose
>a problem, and 2) nor should new static members.

Sounds good to me.

>Anyhow, as I've said, I think it is doable, but I'm not convinced that
>it is worth it. What I'd suggest is that you write up some sort of a
>proposal just allowing additional non-virtual member functions and
>single, non-virtual inheritance, but with a very good rationale
>section -- why this is needed. If the rationale is convincing, we can
>think about what else can be allowed, but discussing the details
>before having convinced people that the extension is in any way useful
>is not particularly productive.
>
>(I know you think it is useful, but I'm not sure you've convinced
>anyone else yet. I think that it could be slightly useful, but not
>useful enought to warrent additional special cases which have to be
>taught -- the language is complicated enough as is.)

Okay, I'll write up a proposal with a rationale as to why this is
useful, and post it here. Thanks for the feedback!

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---

Dave Harris

unread,
May 16, 2002, 7:50:25 AM5/16/02
to
ka...@alex.gabi-soft.de (James Kanze) wrote (abridged):

> Off-hand, I'd start with only allowing non-virtual member functions,
> although 1) things like typedef's, enum etc. certainly shouldn't pose
> a problem, and 2) nor should new static members.

How valuable are the implementation freedoms that would be lost by this?
I am thinking here of an implementation which chooses to make PODs
compatible with C, but uses a wacky scheme for all non-PODs. For
example, non-PODs could always have a vtable which stores extra
information for debugging or profiling or something.

I don't know of any implementation which does this, but I wouldn't want
to rule it out. Contemporary implementations are usually optimised for
efficiency over safety. Perhaps in another 5 or 10 years that fashion
will reverse. Maybe we will start to see "managed C++" execution models,
similar in spirit to C# and Java. Who knows?

It seems to me that the proposal amounts to saying that a class which
inherits from a POD, and satisfies your restrictions, is a kind of
quasi-POD. If we go this route maybe we should make it a full POD
instead. For example, allowing it to be copied with memcopy() as well as
deleted via a pointer to its base class.


> Anyhow, as I've said, I think it is doable, but I'm not convinced that
> it is worth it.

Me neither. Wouldn't it lead to fragile designs? Suppose I publish a
base class for you to derive from, but which doesn't have a virtual
destructor and which I want to delete via pointers to the base. You are
allowed to add member functions but not to add instance variables. Is
this set of constraints really useful? How long before some maintenance
programmer forgets and adds an instance variable anyway?

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

---

Paul Mensonides

unread,
May 16, 2002, 7:50:30 AM5/16/02
to
> I choose the angle brackets for two reasons:
>
> 1) "<type>literal" does not seem, at first thought, as something that can be
> used in any other situation and I want the parser for a C++ compiler
> implementation to be able to pick it up easily.
> 2) It mimics the C++ casting operations and I see my solution as sort of a
> cast. Of course I am not really casting a literal to another type, but just
> telling the compiler to treat my literal as a specific type, but the concept
> of specifying a type is similar.
>
> Of course in order to not break existing code, the current methods of
> specifying literals of various types should still be supported, so I see my
> proposal as an addition and not a replacement. Obviously the addition makes
> using literals in templated functions and classes easier.
>
> I agree the exact syntax for this idea is not a serious issue and I would
> defer to another syntax which would make it easy to specify and which would
> cause the C++ compiler parser few problems. But I do like my syntax for the
> reasons above.

You don't really need any brackets. You could simply prefix it with a type. In
the case of literals, this wouldn't break anything either. And it would be
somewhat similar to the existing L"string" notation (except whitespace wouldn't
matter).

template<class T> const T* f() {
return T "some text"
}

Either way would be okay with me. I just think we have enough parenthesis and
brackets of various kinds already--and I hate counting parenthesis, etc.. :)

Paul Mensonides

Felix Shvaiger

unread,
May 16, 2002, 1:08:33 PM5/16/02
to
"John Nagle" <na...@animats.com> wrote in message
news:3CE15DD...@animats.com...

> >>From: Felix Shvaiger [mailto:fshv...@cisco.com]
> >>Sent: 14 May 2002 09:28
> >>To: Tom Puverle
> >>Subject: Re: C++0x Wish list
>
> > Some keyword like 'noinherit' which mean,
> > that virtual method could not be inherited by
> > derived class, but rather must be overrided
> > in each direct or undirect derived class.
>
>
> I'm not entirely sure what that means.
>
> I suggest simply prohibiting the overriding of non-virtual functions.
> That would seem to provide the functionality requested. It's almost
> always an error when someone overrides a non-virtual function.
> On the rare occasions that you really want to do that, you can
> use a different function name.
>
> John Nagle
>

No. No. No. See example in original post.
The idea is to make it clear to compiler and user that
some VIRTAUL (but not abstract) method MUST BE OVERRIDED
in every derived class.
For example method 'getClassName' MUST BE VIRTUAL and
MUST BE OVERRIDED in each and every derived class
in order to return different names for each and every class.
It will be error if objects of two different classes will return same
ClassName.

Felix Shvaiger

Ken Hagan

unread,
May 16, 2002, 1:12:29 PM5/16/02
to
"Edward Diener" <eldi...@earthlink.net> wrote...

>
> I choose the angle brackets for two reasons:
>
> 1) "<type>literal" does not seem, at first thought, as something that can
be
> used in any other situation and I want the parser for a C++ compiler
> implementation to be able to pick it up easily.
> 2) It mimics the C++ casting operations and I see my solution as sort of a
> cast.

You will almost certainly find that

literal_cast<T>("string")

is easiest to parse. It is possibly also the easiest to teach. Yes it
is a little verbose, how often do you expect to use it? The motivation
so far appears to be mostly for writing industrial strength templates,
which is a sufficiently "guru" activity that the verbosity might be
tolerated.

> Of course I am not really casting a literal to another type, but just
> telling the compiler to treat my literal as a specific type, but the
> concept of specifying a type is similar.

I'm not sure reinterpret_cast does _much_ more than "tell the compiler
to treat something as something else.

Claus Rasmussen

unread,
May 16, 2002, 3:07:37 PM5/16/02
to
Pete Becker wrote:

> Let me suggest a different approach. Instead of asking about language
> features, put together a list of problems that aren't easily solved in

> the language as it exists today. ..................................

Good suggestion. Here is the pet peeves of mine:

1). A simple way of deriving classes without having to re-specify the
constructors of the parent class.

Often you derive from a base class only to add one or two methods.
If the parent class has a lot of constructors and if you wan't to
keep those constructors in your derived class you have no other
option than re-specifying those constructors in your derived class.

This could be solved by allowing constructors to be inherited iff
the derived class adds no new (data-) members. Anonymous classes
would also come handy in some situations.

2). A simple way of declaring function objects close to their usage.

Defining your own one-off STL compatible algorithms often displaces
the implementation of the algorithm far from the often singular usage
of the algorithm and thus obscuring the intention of the program.

Compare

list<int> l;
for (list::iterator i = l.begin(); i != l.end(); ++i)
// do some computation

and

struct do_some_compuation {
void operator()(int i) const { // do something }
};

// ...

for_each(l.begin(), l.end(), do_some_computation);

The first example makes it clear to the reader of the code what the
intention is while the second version would often require the reader
to scroll some pages back to find the implementation of the algorithm.

A solution could be to standardize the Boost lambda library or to
augment the language with facilities for such lambda constructs. IMO
the last solution is preferred.

3). Objects in containers

The STL containers are not well-suited for object-orientated
programming when the objects in question don't have a reasonable
copy-semantics. This forces you to use pointers in your containers
and results in cumbersome indirections whenever you wan't to use
an algorithm over those objects in the container.

This could be solved by making references assignable (but could
possibly open for a lot of other problems too).

4). Clean-up of std::string

The string interface is horribly bloated. This is a problem when
you wan't to create a std::string lookalike class - like a class
based on variable sized UTF-8 characters.

5). Addition of UCS-2 or UCS-4 string classes

The support for internationalized strings is almost absent from the
standard.


Yours

-Claus

Steve Heller

unread,
May 16, 2002, 3:07:17 PM5/16/02
to
Howard Gardner <use...@hgardner.com> wrote:

>Steve Heller wrote:
>> Howard Gardner <use...@hgardner.com> wrote:
>>
>>>struct no_virtual_destructor{};
>>>
>>>struct virtual_destructor{ virtual ~virtual_destructor(){} };
>>>
>>>template<..., class destructor_policy = no_virtual_destructor>
>>> class basic_string : public destructor_policy {...};
>>>
>>>The default case is unchanged, so it shouldn't break anything.
>>>
>>>Someone who wants to subclass it can just change the destructor policy
>>>and be on their merry way.
>>>
>>>It will also let people who want to "abuse" the mechanism and make other
>>>functions virtual.
>>>
>>>It doesn't change the argument about subclassing at all, but it sure
>>>makes it less interesting.
>>
>>
>> I'll go for this solution, assuming I understand it. Can you give an
>> example where the "virtual_destructor" struct is used?
>>
>
>Yes, there's one in Steve Heller's upcoming book, in the section titled
>"Extending the functionality of strings." ;)
>
>It would allow this to work without the potential for violation of LSP
>or undefined behavior:
>
>class xstring : public basic_string <..., virtual_destructor> {...};
>
>The full behavior of basic string is inherited safely.

So "virtual_destructor" would specify a policy for a specific
instantiation of basic_string?

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---

Pete Becker

unread,
May 16, 2002, 3:08:28 PM5/16/02
to
Felix Shvaiger wrote:
>
> No. No. No. See example in original post.
> The idea is to make it clear to compiler and user that
> some VIRTAUL (but not abstract) method MUST BE OVERRIDED
> in every derived class.
> For example method 'getClassName' MUST BE VIRTUAL and
> MUST BE OVERRIDED in each and every derived class
> in order to return different names for each and every class.
> It will be error if objects of two different classes will return same
> ClassName.
>

Why do you wnt to restrict how implementors of derived classes provide
this capability? In particular, this construct would prohibit the
following:

class Base
{
public:
virtual string getClassName() = MUST_OVERRIDE { ..... };
};

class Intermediate : public Base
{
public:
string getClassName() { return getRealName(); }
virtual string getRealName() { ..... };
};

As the designer of Base, it's your job to ensure that Base works
correctly, and that includes specifying what a call to
Derived::getClassName should do. It is not your job to specify how
Derived::getClassName does its job.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Garry Lancaster

unread,
May 16, 2002, 3:08:00 PM5/16/02
to
Dave Harris:

> Maybe we will start to see "managed C++" execution models,
> similar in spirit to C# and Java. Who knows?

There's one already in Visual Studio.net. It will be interesting to
see if it takes off.

Kind regards

Garry Lancaster
Codemill Ltd
Visit our web site at http://www.codemill.net

---

James Kanze

unread,
May 16, 2002, 3:08:45 PM5/16/02
to
bran...@cix.co.uk (Dave Harris) writes:

|> ka...@alex.gabi-soft.de (James Kanze) wrote (abridged):
|> > Off-hand, I'd start with only allowing non-virtual member
|> > functions, although 1) things like typedef's, enum
|> > etc. certainly shouldn't pose a problem, and 2) nor should new
|> > static members.

|> How valuable are the implementation freedoms that would be lost by
|> this? I am thinking here of an implementation which chooses to
|> make PODs compatible with C, but uses a wacky scheme for all
|> non-PODs. For example, non-PODs could always have a vtable which
|> stores extra information for debugging or profiling or something.

I don't think that that would pose a problem. The freedom that is
lost is to do something radically different in the derived class than
what one does in the base class.

Generally speaking, the freedom for the implementation seems a minimal
issue in this case. The loss of freedom is very small. (On the other
hand, for the moment, the benefits also seem exceedingly small.)

|> I don't know of any implementation which does this, but I wouldn't
|> want to rule it out. Contemporary implementations are usually
|> optimised for efficiency over safety. Perhaps in another 5 or 10
|> years that fashion will reverse. Maybe we will start to see
|> "managed C++" execution models, similar in spirit to C# and
|> Java. Who knows?

|> It seems to me that the proposal amounts to saying that a class
|> which inherits from a POD, and satisfies your restrictions, is a
|> kind of quasi-POD. If we go this route maybe we should make it a
|> full POD instead. For example, allowing it to be copied with
|> memcopy() as well as deleted via a pointer to its base class.

Iteresting idea. No comment. (As I said, I don't think that this is
important. But since the original poster apparently did, I thought
I'd give some food for thought.)

|> > Anyhow, as I've said, I think it is doable, but I'm not
|> > convinced that it is worth it.

|> Me neither. Wouldn't it lead to fragile designs? Suppose I publish
|> a base class for you to derive from, but which doesn't have a
|> virtual destructor and which I want to delete via pointers to the
|> base. You are allowed to add member functions but not to add
|> instance variables. Is this set of constraints really useful? How
|> long before some maintenance programmer forgets and adds an
|> instance variable anyway?

The one case where I thought it might be useful is in the case of
arrays. There have been one or two times where I thought it might be
useful to derive in order to provide a constructor with special
initialization, then treat the allocated array as an array of the base
class. A stupid example:

struct InitializedString : public std::string
{
InitializedString() : std::string( "Big deal" ) {}
}

std::string* array = new InitializedString[ 200 ] ;

My proposal, at the time, would have been to allow nothing but
constructors in the derived class -- what I would have called trivial
derivation.

As I say, it's doable, but after thinging about it, I decided that it
wasn't worth it. The gain really isn't that much, and it is one more
rule to learn. (It's not as if C++ were too simple otherwise.)

--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---

Francis Glassborow

unread,
May 16, 2002, 4:25:51 PM5/16/02
to
In article <cnOE8.641$Fs2....@news8-gui.server.ntli.net>, Garry
Lancaster <glanc...@ntlworld.com> writes

>Dave Harris:
>> Maybe we will start to see "managed C++" execution models,
>> similar in spirit to C# and Java. Who knows?
>
>There's one already in Visual Studio.net. It will be interesting to
>see if it takes off.

True, but as Stan Lippman pointed out at the ACCU Spring Conference, it
is only the first version and a great deal of work needs to be done to
make it close to a genuine implementation of C++ (work that he is
committed to seeing done)


--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

Francis Glassborow

unread,
May 16, 2002, 4:39:53 PM5/16/02
to
In article <ac02ii$5dv$1...@sunsite.dk>, Claus Rasmussen
<c...@cc-consult.dk> writes

>1). A simple way of deriving classes without having to re-specify the
> constructors of the parent class.
>
> Often you derive from a base class only to add one or two methods.
> If the parent class has a lot of constructors and if you wan't to
> keep those constructors in your derived class you have no other
> option than re-specifying those constructors in your derived class.
>
> This could be solved by allowing constructors to be inherited iff
> the derived class adds no new (data-) members. Anonymous classes
> would also come handy in some situations.

This is under consideration but it isn't that simple. What about the
assignment operator, the dtor, other member functions that return the
class type by value, reference or pointer, parameters of those types
etc.

>
>2). A simple way of declaring function objects close to their usage.
>
> Defining your own one-off STL compatible algorithms often displaces
> the implementation of the algorithm far from the often singular usage
> of the algorithm and thus obscuring the intention of the program.

I don't think you meant what you wrote, these aren't algorithms but
functions or functors being used by STL 'algorithms'.


>
> Compare
>
> list<int> l;
> for (list::iterator i = l.begin(); i != l.end(); ++i)
> // do some computation
>
> and
>
> struct do_some_compuation {
> void operator()(int i) const { // do something }
> };
>
> // ...
>
> for_each(l.begin(), l.end(), do_some_computation);
>
> The first example makes it clear to the reader of the code what the
> intention is while the second version would often require the reader
> to scroll some pages back to find the implementation of the algorithm.
>
> A solution could be to standardize the Boost lambda library or to
> augment the language with facilities for such lambda constructs. IMO
> the last solution is preferred.
>
>3). Objects in containers
>
> The STL containers are not well-suited for object-orientated
> programming when the objects in question don't have a reasonable
> copy-semantics. This forces you to use pointers in your containers
> and results in cumbersome indirections whenever you wan't to use
> an algorithm over those objects in the container.
>
> This could be solved by making references assignable (but could
> possibly open for a lot of other problems too).

I think that is not a suitable solution for C++. What is wrong with a
suitable smart pointer or some other form of proxy object. Perhaps
someone could come up with some containers that work through their own
smart pointer.

>
>4). Clean-up of std::string
>
> The string interface is horribly bloated. This is a problem when
> you wan't to create a std::string lookalike class - like a class
> based on variable sized UTF-8 characters.

Well i think this is much more than a cleanup. We need a radical
redesign (something I have been mumbling about for a long time.

>
>5). Addition of UCS-2 or UCS-4 string classes
>
> The support for internationalized strings is almost absent from the
> standard.

Yes, but they keep changing the ground and there is much more to
internationalisation than just characters. I do not know of any language
that gets even close to getting it right.

--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

John G Harris

unread,
May 16, 2002, 5:00:49 PM5/16/02
to
In article <02yE8.2313$UL2.1...@newsfep1-win.server.ntli.net>, Garry
Lancaster <glanc...@ntlworld.com> writes

>John G. Harris:
>> If having the same identifier doesn't guarantee that interworking is
>> possible then I don't understand why an ISO-defined identifier would
>> benefit anyone.
>
>I'm not sure what you mean by that. You need much
>more than consistent type names for portable
>code and producing portable serialised objects,

Is this the problem the proposal is aimed at ?

>but
>it's one step in the right direction.

If it is then I cannot see any solution that could be put into an ISO
standard. It would need an identifier registration scheme, something
like the registration scheme for URL domain names (enter lawyers, stage
right).

John
--
John Harris
mailto:jo...@jgharris.demon.co.uk

Howard Gardner

unread,
May 16, 2002, 5:16:42 PM5/16/02
to

Exactly.

It works for the same reason that this works:

struct no_virtual_destructor{};

struct virtual_destructor{ virtual ~virtual_destructor(){} };

template <class destructor_policy>
class some_class
:
public destructor_policy
{
public:
void func(void) {}
};

some_class< no_virtual_destructor > does not have a virtual destructor.

some_class< virtual_destructor > has a virtual destructor.

The only potential pitfall that I see in the context of the standard
library is that it might be abuesed. This also works, and accounting for
the possibility might complicate implementations of the containers and
strings:

struct abusive
{
virtual ~virtual_destructor(){}
virtual void func(void){}
};

some_class< abusive > has a virtual destructor, which is what we meant
to allow. func is virtual too, though, and that could be problematic.

I've played with this idea (inheriting from a template parameter) a lot.
It's amusing.

--
I <3 Comeau C++: http://www.comeaucomputing.com

---

Garry Lancaster

unread,
May 17, 2002, 1:02:03 PM5/17/02
to
> >John G. Harris:
> >> If having the same identifier doesn't guarantee that interworking is
> >> possible then I don't understand why an ISO-defined identifier would
> >> benefit anyone.

Garry Lancaster:


> >I'm not sure what you mean by that. You need much
> >more than consistent type names for portable
> >code and producing portable serialised objects,

John G. Harris:


> Is this the problem the proposal is aimed at ?

I would say so, although I didn't make the original
suggestion.

> >but
> >it's one step in the right direction.

> If it is then I cannot see any solution that could be put into an ISO
> standard. It would need an identifier registration scheme, something
> like the registration scheme for URL domain names (enter lawyers, stage
> right).

Before moving to a more exotic scheme we need
to thoroughly examine the more obvious alternatives.
What is wrong with std::vector<int> being known as
"std::vector<int>"?

Kind regards

Garry Lancaster
Codemill Ltd
Visit our web site at http://www.codemill.net

---

Natale Fietta

unread,
May 17, 2002, 1:03:26 PM5/17/02
to
On Thu, 16 May 2002 21:16:42 GMT, Howard Gardner <use...@hgardner.com>
wrote:

>The only potential pitfall that I see in the context of the standard
>library is that it might be abuesed. This also works, and accounting for
>the possibility might complicate implementations of the containers and
>strings:
>
>struct abusive
>{
> virtual ~virtual_destructor(){}
> virtual void func(void){}
>};
>
>some_class< abusive > has a virtual destructor, which is what we meant
>to allow. func is virtual too, though, and that could be problematic.

Another little pitfall is the fact that some_class<virtual_destructor>
and some_class<no_virtual_destructor> are unrelated class, but i
suppose this is not a serious problem.

Instead the described abuse is more annoying (maybe "dangerous" is a
more precise word), what about this instead ?

template <bool>
struct destructor {};

template<>
struct destructor<true> { virtual ~destructor() {} };

template <bool virtual_destructor_policy>
class some_class : public destructor<virtual_destructor_policy>
{
public:
void func(void) {}
};

This give us the freedom of select virtual or not virtual destructor,
whitout the backdoor for "virtualize" other member functions.

>I've played with this idea (inheriting from a template parameter) a lot.
>It's amusing.

Yes, very interesting.

Regards,
Natale Fietta

Dave Harris

unread,
May 17, 2002, 1:17:52 PM5/17/02
to
ka...@alex.gabi-soft.de (James Kanze) wrote (abridged):
> I don't think that that would pose a problem. The freedom that is
> lost is to do something radically different in the derived class than
> what one does in the base class.

Yes. I am thinking of the case where the base class is a POD, and
therefore heavily restricted. Currently a derived class is never a POD so
not subject to the same restrictions. For example, it doesn't have to be
in contiguous memory.

I am not sure what can currently be done with this. For example, is it
possible to implement inheritance using pointers, like:

class Derived {
Base __*pBase;
};

rather than by embedding a Base subobject. In effect, a kind of automatic
pImpl idiom. Sizeof(Derived) would be independent of sizeof(Base),
avoiding some of the fragile base class problems.

As another example, in another thread Fergus Henderson just wrote:

The C++ committee wanted to permit implementations in which
all method calls were implemented in essentially the same
way as virtual method calls,

This kind of thing might lead to wanting a vtable in Derived even though
Derived does not add any virtual functions.

I don't know of any implementation which takes advantages of these
freedoms, so I wonder if they are still taken seriously by the standards
committee.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

---

Edward Diener

unread,
May 17, 2002, 1:41:09 PM5/17/02
to
"Ken Hagan" <K.H...@thermoteknix.co.uk> wrote in message
news:1021541084.24205....@news.demon.co.uk...

> "Edward Diener" <eldi...@earthlink.net> wrote...
> >
> > I choose the angle brackets for two reasons:
> >
> > 1) "<type>literal" does not seem, at first thought, as something that
can
> be
> > used in any other situation and I want the parser for a C++ compiler
> > implementation to be able to pick it up easily.
> > 2) It mimics the C++ casting operations and I see my solution as sort of
a
> > cast.
>
> You will almost certainly find that
>
> literal_cast<T>("string")
>
> is easiest to parse. It is possibly also the easiest to teach. Yes it
> is a little verbose, how often do you expect to use it? The motivation
> so far appears to be mostly for writing industrial strength templates,
> which is a sufficiently "guru" activity that the verbosity might be
> tolerated.

I like your idea of using "literal cast" very much. It is certainly clearer
to the compiler than just <T>"string" and also follows the syntax of other
C++ casting operations. The extra verbosity is mostly irrelevant compared to
the clearness of the syntax.

Howard Gardner

unread,
May 17, 2002, 2:49:26 PM5/17/02
to
Natale Fietta wrote:
> On Thu, 16 May 2002 21:16:42 GMT, Howard Gardner <use...@hgardner.com>
> wrote:
>
> Another little pitfall is the fact that some_class<virtual_destructor>
> and some_class<no_virtual_destructor> are unrelated class, but i
> suppose this is not a serious problem.

Yet another paragraph or subsection in tutorials on the STL. At least
the explanation would be shorter than the "publicly inheriting from a
standard container is perilous" discussion.

>
> Instead the described abuse is more annoying (maybe "dangerous" is a
> more precise word), what about this instead ?

Yes. Maybe. No.

It's never actually caused me a problem. It worries me because I don't
think the world has a lot of experience with the technique. At least, I
haven't seen much discussion of it.

My personal adventure in mastering exception safety has made me much
more cautious. The warts in the standard library--which exist despite
the fact that so many masters of our art payed so much attention to
them--have made me much more cautious.

It's a wonder that I can bring myself to attempt to write code at all ;)

> template <bool>
> struct destructor {};
>
> template<>
> struct destructor<true> { virtual ~destructor() {} };
>
> template <bool virtual_destructor_policy>
> class some_class : public destructor<virtual_destructor_policy>
> {
> public:
> void func(void) {}
> };
>
> This give us the freedom of select virtual or not virtual destructor,
> whitout the backdoor for "virtualize" other member functions.

Yes, that would plug the hole.

I'm not certain that the hole should be plugged. If string and the
containers can be implemented in such a way that they can tolerate the
flexibility--and my experiments with the technique lead me to suspect
that they can--then users might benefit from it.

--
I <3 Comeau C++: http://www.comeaucomputing.com

---

Natale Fietta

unread,
May 20, 2002, 1:27:04 PM5/20/02
to
On Fri, 17 May 2002 18:49:26 GMT, Howard Gardner <use...@hgardner.com>
wrote:

>Yet another paragraph or subsection in tutorials on the STL. At least

>the explanation would be shorter than the "publicly inheriting from a
>standard container is perilous" discussion.

Before reading this thread i was thinking of a totally different
solution, to add a language feature to specificate that a class is a
leaf class, so prohibiting further derivation from it.

something similar to this:

class Base {...};

class Leaf : public Base, underivable {...};
// ^ hypothetical new keyword

class Abuse : public Leaf {...};
// hypothetic compile time error: deriving from underivable class Leaf

Happily this is no more necessary for std::string/containers (if the
proposed template derivation trick is used), but maybe can be useful
for other pourposes...

>> Instead the described abuse is more annoying (maybe "dangerous" is a
>> more precise word), what about this instead ?
>
>Yes. Maybe. No.

I like decise answers ;-)

>It's never actually caused me a problem. It worries me because I don't
>think the world has a lot of experience with the technique. At least, I
>haven't seen much discussion of it.

I definitively do not have ANY experience with this idiom (i read it
the first time in this thread), so i have a lot to learn from this
discussion.

>> This give us the freedom of select virtual or not virtual destructor,
>> whitout the backdoor for "virtualize" other member functions.
>
>Yes, that would plug the hole.
>
>I'm not certain that the hole should be plugged.

Agree, probably the usefulness is more than the danger, at least in
the hand of a competent programmer...

Regards,
Natale Fietta

Mark Jordan

unread,
May 20, 2002, 1:48:24 PM5/20/02
to
"John Nagle" <na...@animats.com> wrote in message
news:3CDF5E87...@animats.com...
>
> The "include" approach to interfaces fosters too
> much unwanted interdependency in large projects. Changing
> the private part of a class forces a recompile of the
> class's users. On large projects, this generates
> huge amounts of irrelevant recompile activity, and then
> trying to avoid those recompiles warps designs out of shape.

I second this. It's my biggest gripe about C++. I'd really like a clean
physical separation of interface from implementation to avoid the
issues above. Other languages have had it for decades!

Cheers,
Mark.

Mark Jordan

unread,
May 20, 2002, 1:48:48 PM5/20/02
to
"Pete Becker" <peteb...@acm.org> wrote in message
news:3CDA7DBA...@acm.org...
> Tom Puverle wrote:
> >
> > I am trying to put together a wish list of language extensions that
people
> > would like to see in C++0x.

>
> Let me suggest a different approach. Instead of asking about language
> features, put together a list of problems that aren't easily solved in
> the language as it exists today. Language features aren't an end in
> themselves, but are a way of solving problems. Focusing initially on
> problems rather than solutions will lead to a better set of solutions.

OK, here's one problem, there's too much tedius typing required for
assembling components via composition.

What we need is some kind of higher level "wrap" operator to automatically
generate inline forwarding functions.

class A
{
public:
int foo1();
int foo2();
};

class B
{
public:
int foo0();

private:
wrap A a; // Exports interface of A straight through to interface of
B, but don't expose 'a' itself.
};

int main()
{
B b;
b.foo0();
b.foo1();
b.foo2();
return 0;
}

It should work for pointer members too. Any comments?

Francis Glassborow

unread,
May 20, 2002, 3:13:06 PM5/20/02
to
In article <acb8qk$f9u$1...@pegasus.csx.cam.ac.uk>, Mark Jordan
<ma...@mrc-lmb.cam.ac.uk> writes

>> the language as it exists today. Language features aren't an end in
>> themselves, but are a way of solving problems. Focusing initially on
>> problems rather than solutions will lead to a better set of solutions.
>
>OK, here's one problem, there's too much tedius typing required for
>assembling components via composition.
>
>What we need is some kind of higher level "wrap" operator to automatically
>generate inline forwarding functions.
>
>class A
>{
> public:
> int foo1();
> int foo2();
>};
>
>class B
>{
> public:
> int foo0();
>
> private:
> wrap A a; // Exports interface of A straight through to interface of
>B, but don't expose 'a' itself.
>};
>
>int main()
>{
> B b;
> b.foo0();
> b.foo1();
> b.foo2();
> return 0;
>}
>
>It should work for pointer members too. Any comments?

Quite a few of us understand the problem but I suspect we can do better
for a solution.


--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

James Dennett

unread,
May 20, 2002, 3:44:37 PM5/20/02
to
Mark Jordan wrote:
> "John Nagle" <na...@animats.com> wrote in message
> news:3CDF5E87...@animats.com...
>
>> The "include" approach to interfaces fosters too
>>much unwanted interdependency in large projects. Changing
>>the private part of a class forces a recompile of the
>>class's users. On large projects, this generates
>>huge amounts of irrelevant recompile activity, and then
>>trying to avoid those recompiles warps designs out of shape.
>
>
> I second this. It's my biggest gripe about C++. I'd really like a clean
> physical separation of interface from implementation to avoid the
> issues above. Other languages have had it for decades!

C++ offers it to you in multiple ways, either with a "pimpl"
(or whatever the latest name for envelope-letter or handle-body
in its general form is), or by using inheritance from an
interface. The fact that it allows you to avoid the (maybe
small) overhead that this layer of abstraction gives does
not mean that you are forced into tight coupling. Are you
wanting to take features away from C++ because people use
C++ to implement their bad designs, or because they use it
to implement their designs badly?

I agree that I'd prefer C++ to have a model for using separately
compiled code which is rather more sophisticated than "#include",
but I don't think that this is one of the reasons for doing so.

--
James Dennett <jden...@acm.org>

Steve Heller

unread,
May 20, 2002, 6:06:05 PM5/20/02
to
"Mark Jordan" <ma...@mrc-lmb.cam.ac.uk> wrote:

This accomplishes essentially the same result as my "using"
inheritance proposal.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt


======================================= MODERATOR'S COMMENT:
Please do not quote the complete text of a significantly
sized message in order to just add one sentence, but rather trim
down the material to only what is needed for context. Thanks.

Pete Becker

unread,
May 20, 2002, 7:37:24 PM5/20/02
to
Felix Shvaiger wrote:
>
> I DO NOT WONT TO RESTRICT how implementors of derived classes provide some
> capability,
> but I DO WANT to give him a BOLD HINT that implementation of virtual method
> in base class
> probably (or almost sure) WOLL NOT WORK CORRECT in derived class -
> so it is highly recommended to provide another implementation specific for
> derived class.
>
> You are quite right - keyword 'noinherit' ( or may be 'explicit' is good
> enough) must be repeated
> in derived class in order to continue this noinherit behavior. So your
> example has to be rewrited:

>
> class Base
> {
> public:
> virtual string getClassName() = MUST_OVERRIDE { ..... };
> };
>
> class Intermediate : public Base
> {
> public:
> string getClassName() { return getRealName(); }
> virtual string getRealName() = MUST_OVERRIDE { ..... };
> };
>
> class Derived : public Intermediate
> {
> public:
> virtual string getRealName() = MUST_OVERRIDE { ..... };
> };
>

I misunderstood your example. Replace 'MUST_OVERRIDE' with '= 0'. It's
already in the language.

Mark Jordan

unread,
May 20, 2002, 9:18:50 PM5/20/02
to
"Steve Heller" <st...@steveheller.com> wrote in message

> >
> >What we need is some kind of higher level "wrap" operator to automatically
> >generate inline forwarding functions.
> >
>
> This accomplishes essentially the same result as my "using"
> inheritance proposal.

References please Steve?
Isn't "using" already rather overloaded for namespaces?

Cheers,
Mark.

Mark Jordan

unread,
May 21, 2002, 1:33:27 AM5/21/02
to
"Francis Glassborow" <francis.g...@ntlworld.com> wrote in message

> >
> >What we need is some kind of higher level "wrap" operator to automatically
> >generate inline forwarding functions.
> >
> Quite a few of us understand the problem but I suspect we can do better
> for a solution.

Great!
Where's the draft proposal outlining a better solution?

Cheers,
Mark.

John Nagle

unread,
May 21, 2002, 1:34:30 AM5/21/02
to
Pete Becker is right, but C++ really should prevent
overriding of a non-virtual method. That's almost always
an error, and it's hard to find, because it's a non-local error,
where two things far apart textually are inconsistent.
Those are the kinds of errors you want the compiler to
catch if at all possible.

I'd just prohibit it. No new syntax; just make it
an error to override a non-virtual method. The very
rare occasions in which it is useful don't justify the
large number of errors that occur when it's wrong.

John Nagle
Animats

Pete Becker wrote:


> I misunderstood your example. Replace 'MUST_OVERRIDE' with '= 0'. It's
> already in the language.

---

Steve Heller

unread,
May 21, 2002, 1:34:59 AM5/21/02
to
"Mark Jordan" <Mark_...@nospam.btinternet.com> wrote:

>"Steve Heller" <st...@steveheller.com> wrote in message
>> >
>> >What we need is some kind of higher level "wrap" operator to automatically
>> >generate inline forwarding functions.
>> >
>>
>> This accomplishes essentially the same result as my "using"
>> inheritance proposal.
>
>References please Steve?
>Isn't "using" already rather overloaded for namespaces?

Not in the way I've suggested, e.g.,

class A : using B

would mean that objects of type A could be called with functions
declared in B, but A objects could not be substituted for B objects.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---

Mark Jordan

unread,
May 21, 2002, 12:35:27 PM5/21/02
to
"James Dennett" <jden...@acm.org> wrote in message news:3CE9510C...@acm.org...

> Mark Jordan wrote:
> > "John Nagle" <na...@animats.com> wrote in message
> > news:3CDF5E87...@animats.com...
> >
> >> The "include" approach to interfaces fosters too
> >>much unwanted interdependency in large projects. Changing
> >>the private part of a class forces a recompile of the
> >>class's users. On large projects, this generates
> >>huge amounts of irrelevant recompile activity, and then
> >>trying to avoid those recompiles warps designs out of shape.
> >
> > I second this. It's my biggest gripe about C++. I'd really like a clean
> > physical separation of interface from implementation to avoid the
> > issues above. Other languages have had it for decades!
>
> C++ offers it to you in multiple ways, either with a "pimpl"
> (or whatever the latest name for envelope-letter or handle-body
> in its general form is), or by using inheritance from an
> interface.

Yes, I know this, but I don't see why I should have to
write all those forwarding functions to achieve something
so fundamental. Do you enjoy writing code in assembly
language? ;-)

> Are you
> wanting to take features away from C++ because people use
> C++ to implement their bad designs, or because they use it
> to implement their designs badly?

I don't understand what you are saying. What features
would such a proposal take away?

> I agree that I'd prefer C++ to have a model for using separately
> compiled code which is rather more sophisticated than "#include",
> but I don't think that this is one of the reasons for doing so.

Not alone, but one of many nails in the coffin ;-)

Cheers,
Mark.

Francis Glassborow

unread,
May 21, 2002, 12:39:56 PM5/21/02
to
In article <acc6o6$rf1$1...@knossos.btinternet.com>, Mark Jordan
<Mark_...@nospam.btinternet.com> writes

>"Francis Glassborow" <francis.g...@ntlworld.com> wrote in message
>> >
>> >What we need is some kind of higher level "wrap" operator to automatically
>> >generate inline forwarding functions.
>> >
>> Quite a few of us understand the problem but I suspect we can do better
>> for a solution.
>
>Great!
>Where's the draft proposal outlining a better solution?

Be patient. I certainly want to look at all the options before producing
a specific proposal.


--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

Felix Shvaiger

unread,
May 21, 2002, 12:40:10 PM5/21/02
to

"Pete Becker" <peteb...@acm.org> wrote in message
news:3CE98786...@acm.org...

It will prevent class Base from being instantiated.
I want class Base be able to produce instances
(not abstract) because Base::getClassName
works correct for class Base and
objects of class Base will work just fine.
But I want to prevent class Intermediate from being
instantiated if it doesn't override getClassName because
Base::getClassName works incorrect for class Intermediate
and therefore objects of such class will be broken.

The same for Intermediate::getRealName
and Derived::getRealName.

==============
Felix Shvaiger
fshv...@cisco.com

Mark Jordan

unread,
May 21, 2002, 12:40:14 PM5/21/02
to
"Steve Heller" <st...@steveheller.com> wrote in message
news:lhjjeu8nfdm6pllac...@4ax.com...

> "Mark Jordan" <Mark_...@nospam.btinternet.com> wrote:
>
> >"Steve Heller" <st...@steveheller.com> wrote in message
> >> >
> >> >What we need is some kind of higher level "wrap" operator to
automatically
> >> >generate inline forwarding functions.
> >>
> >> This accomplishes essentially the same result as my "using"
> >> inheritance proposal.
> >
> >References please Steve?
> >Isn't "using" already rather overloaded for namespaces?
>
> Not in the way I've suggested, e.g.,
>
> class A : using B
>
> would mean that objects of type A could be called with functions
> declared in B, but A objects could not be substituted for B objects.

Does "using" have finer granularity, ie at member function level?

For example, I would commonly want to make the constructors
destructors and operators invisible to clients of A. Would there be
any clash with namespaces then?

Cheers,
Mark.

Mark Jordan

unread,
May 21, 2002, 12:40:24 PM5/21/02
to
> Tom Puverle wrote:
> > I am trying to put together a wish list of language extensions that
people
> > would like to see in C++0x.

Slap me down again, but I have yet more wishes ;-)

1.
Integral language support for preconditions/postconditions and
invariants to help writing more formal and correct software
components.

2.
You know how we have a "this" pointer, well I'd like to see
a "parent" pointer for nested classes. I needed this a while ago
for implementing "attribute-style" member objects. I'm sure
there are many other uses.

class A
{
public:
virtual void foo();

private:
class B
{
void dofoo() { parent->foo(); }
};
};


3.
The other thing that would be nice is a real compile-time meta-language
built on top of C++. This would help enormously with the generation of
differerent variants of library components at compile time. Using templates
for this is really an ugly hack IMO!

Mark Jordan

unread,
May 21, 2002, 2:03:09 PM5/21/02
to
"Francis Glassborow" <francis.g...@ntlworld.com> wrote in message >
<Mark_...@nospam.btinternet.com> writes

> >> >
> >> >What we need is some kind of higher level "wrap" operator to automatically
> >> >generate inline forwarding functions.
> >> >
> >Where's the draft proposal outlining a better solution?
>
> Be patient. I certainly want to look at all the options before producing
> a specific proposal.

Can you at least enumerate the options then?

Thanks,
Mark.

xle...@qmailcomq.com

unread,
May 21, 2002, 2:35:49 PM5/21/02
to
Currently enums are the only (potentially) named scopes that inject
the names declared within them into the surrounding scope at all times,
and there is no way to prevent it. Making enums non-injecting by default
will fix this inconsistency. In compatibility mode,
"using enum X;" will be implied after a declaration of enum X.

Leo

Steve Heller

unread,
May 21, 2002, 2:36:53 PM5/21/02
to
"Mark Jordan" <ma...@mrc-lmb.cam.ac.uk> wrote:

>"Steve Heller" <st...@steveheller.com> wrote in message
>news:lhjjeu8nfdm6pllac...@4ax.com...
>> "Mark Jordan" <Mark_...@nospam.btinternet.com> wrote:
>>
>> >"Steve Heller" <st...@steveheller.com> wrote in message
>> >> >
>> >> >What we need is some kind of higher level "wrap" operator to
>automatically
>> >> >generate inline forwarding functions.
>> >>
>> >> This accomplishes essentially the same result as my "using"
>> >> inheritance proposal.
>> >
>> >References please Steve?
>> >Isn't "using" already rather overloaded for namespaces?
>>
>> Not in the way I've suggested, e.g.,
>>
>> class A : using B
>>
>> would mean that objects of type A could be called with functions
>> declared in B, but A objects could not be substituted for B objects.
>
>Does "using" have finer granularity, ie at member function level?
>
>For example, I would commonly want to make the constructors
>destructors and operators invisible to clients of A. Would there be
>any clash with namespaces then?

My proposal has nothing to do with namespaces. In the grand old
tradition of C++ keyword overloading, I'm reusing the keyword "using"
to mean something almost, but not quite, completely unlike its current
uses.

--
Steve Heller
http://www.steveheller.com
Author of "Learning to Program in C++", "Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

---

Francis Glassborow

unread,
May 21, 2002, 7:05:28 PM5/21/02
to
In article <acde3b$msi$1...@pegasus.csx.cam.ac.uk>, Mark Jordan
<ma...@mrc-lmb.cam.ac.uk> writes

>Slap me down again, but I have yet more wishes ;-)

You still have it the wrong way round. Committee members are not going
to look at feature proposals, only at proposed solutions to problems so
first you have to identify and explain the problem. If you want Eiffel,
use it.

--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

Sungbom Kim

unread,
May 21, 2002, 9:30:33 PM5/21/02
to
Mark Jordan wrote:
>
> 2.
> You know how we have a "this" pointer, well I'd like to see
> a "parent" pointer for nested classes. I needed this a while ago
> for implementing "attribute-style" member objects. I'm sure
> there are many other uses.
>
> class A
> {
> public:
> virtual void foo();
>
> private:
> class B
> {
> void dofoo() { parent->foo(); }
> };
> };

I'm afraid it's not well defined.

void A::static_member_function()
{
B b;
b.dofoo();
}

Now, to which A should the parent pointer of B point?

The situation is worse when B is defined in the public area of A;
anyone could instantiate A::B, in which case B has no parent of type A!

A possible workaround is to initialise B with a pointer or reference
to A through B's constructor:

class A::B
{
A* parent;
public:
B(A* a) : parent(a) { }
void dofoo() { parent->foo(); }
};

A::A(/*...*/) : member_B(this), /*...*/ { /*...*/ }

--
Sungbom Kim <musi...@bawi.org>

David Rasmussen

unread,
May 22, 2002, 1:02:17 PM5/22/02
to
Francis Glassborow wrote:
> In article <acde3b$msi$1...@pegasus.csx.cam.ac.uk>, Mark Jordan
> <ma...@mrc-lmb.cam.ac.uk> writes
>
>> Slap me down again, but I have yet more wishes ;-)
>
>
> You still have it the wrong way round. Committee members are not going
> to look at feature proposals, only at proposed solutions to problems so
> first you have to identify and explain the problem. If you want Eiffel,
> use it.
>

While the idea of keeping the problem/solution relationship in mind
while proposing new language features is a good idea, I can't understand
this religious insisting on lack of generality. Sometimes, a good way to
do such things, is to step back and look at the bigger picture, and just
brainstorm away. For instance, if you are proposing a well thought-out,
well-designed general compile-time language on top of C++, instead of
the template hacking, how can you possibly express that with an example
solution? Of course, you could give some examples where this could be
useful, but the point of such a general thing is that it is... well,
general. If people in the standards comittee can't see the potential
usefulness of such a general thing, then there's no hope.

Also, a comment like "If you want Eiffel, use it" is not very wise I
think. Why shouldn't C++ have some feature if it makes the language
better, even if the feature comes from another language? Most features
in C++ are stolen from other languages.

I think many of his proposals are very much to the point.

/David

Natale Fietta

unread,
May 22, 2002, 1:04:35 PM5/22/02
to
On Tue, 21 May 2002 18:36:53 GMT, Steve Heller <st...@steveheller.com>
wrote:

> My proposal has nothing to do with namespaces. In the grand old
>tradition of C++ keyword overloading, I'm reusing the keyword "using"
>to mean something almost, but not quite, completely unlike its current
>uses.

Are you sure ?

If i understand it correctly the "using derivation" proposal mean that
having this base class:

class Base
{
public:
Base(some_params);
void publicFunc();
protected:
void protectedFunc();
private:
void privateFunc();
};

then this derivation:

class Derived : using Base
{
};

it is a short-hand for this:

class Derived : private Base
{
public:
Derived(some_params) : Base(some_params) {}
using Base::publicFunc;
protected:
using Base::protectedFunc;
};

so i see it as a natural extension of a current use of "using", not a
totally (not even partially) unrelated new use of the same keyword.

Regards,
Natale Fietta

Hyman Rosen

unread,
May 22, 2002, 1:55:52 PM5/22/02
to
David Rasmussen wrote:
> While the idea of keeping the problem/solution relationship in mind
> while proposing new language features is a good idea, I can't understand
> this religious insisting on lack of generality.

He's not insisting on a lack of generality. He's saying that the next
version of C++ is going to be concentrating on solving problems within
current C++, not making dramatic changes to the language. That means
that your favorite feature from another language is unlikely to be
added.

Furthermore, most of the "proposals" that show up are poorly thought-out.
They seek to scratch some specific itch, but they seldom include a
proper analysis of how the feature interacts with C++ as a whole. They
are mostly requests for someone else to do the hard work, so it's not
surprising that the someone elses are saying "no".

> For instance, if you are proposing a well thought-out, well-designed
> general compile-time language on top of C++

If you could actually provide this, somone might listen.
If you are saying somebody *should* provide this, forget it.
I have not seen any such thing, so I think we're in case two.

Francis Glassborow

unread,
May 22, 2002, 4:08:01 PM5/22/02
to
In article <3CE9BF28...@animats.com>, John Nagle
<na...@animats.com> writes

> I'd just prohibit it. No new syntax; just make it
>an error to override a non-virtual method. The very
>rare occasions in which it is useful don't justify the
>large number of errors that occur when it's wrong.

I think that is a complete non-starter. However much many of us abhor
the use of derivation to tweak a type, it is often done and in good
hands it does not cause errors.

--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

James Kanze

unread,
May 22, 2002, 4:10:11 PM5/22/02
to
John Nagle <na...@animats.com> writes:

|> Pete Becker is right, but C++ really should prevent
|> overriding of a non-virtual method. That's almost always an
|> error, and it's hard to find, because it's a non-local error,
|> where two things far apart textually are inconsistent. Those are
|> the kinds of errors you want the compiler to catch if at all
|> possible.

|> I'd just prohibit it. No new syntax; just make it an error
|> to override a non-virtual method. The very rare occasions in
|> which it is useful don't justify the large number of errors that
|> occur when it's wrong.

My experience is just the opposite. I've not often overriden a
non-virtual function, but when I have, I did so without knowing it,
and I wanted the results I got.

Normally, I would argue that the author of the derived class should
not even know the names of private functions other than the ones he
should override. (This is, in fact, one of the arguments against
private virtual functions -- the author of the derived class should
not have to even look at the private section of the class definition.)
Given this, what is to prevent name clashes, if name clashes are made
illegal?

--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

Francis Glassborow

unread,
May 22, 2002, 4:16:34 PM5/22/02
to
In article <ace1in$ho1$1...@paris.btinternet.com>, Mark Jordan
<Mark_...@nospam.btinternet.com> writes

>"Francis Glassborow" <francis.g...@ntlworld.com> wrote in message >
><Mark_...@nospam.btinternet.com> writes
>> >> >
>> >> >What we need is some kind of higher level "wrap" operator to automatically
>> >> >generate inline forwarding functions.
>> >> >
>> >Where's the draft proposal outlining a better solution?
>>
>> Be patient. I certainly want to look at all the options before producing
>> a specific proposal.
>
>Can you at least enumerate the options then?

Not easily. We have varying concepts of using directives either applied
to private base or to a member, we have Steve Heller's using
inheritance, we have strong typedefs with extensions just to mention the
ones that come to mind. The point is that each possibility meets the
central issue but has different utility and side benefits as well as
problems. If you want to write a paper detailing the problem, proposing
a solution and examining its implications to the rest of the language,
please do so. OTOH if you just want to pick holes in someone else's
work, you will have to wait. Some of us have a lot of different things
to do :-)

--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---

It is loading more messages.
0 new messages