Topic: Namespace of ISO C++0x standard library


Author: "Garry Lancaster" <glancaster@ntlworld.com>
Date: Fri, 8 Feb 2002 16:07:00 GMT
Raw View
Greg Comeau:
> Actually, if folks have questions they want to
> see addressed, they should post them either
> here or in email, and I'll probably be glad to
> maintain a list (and their responses) in
> some way, shape or form, either in the docs
> or in techtalk/templates,
> realizing that it may not occur immediately.

OK. I have a single question about export
really. But it's quite long and I suspect the
answer may be too. Anyway, here goes.

We can consider any C++ source file as
a collection of declarations and definitions
(at least I do, that may not be the correct
standardese, but I hope you can follow).
This includes those declarations and
definitions actually present in the source file
and those from header files that are #included
directly or indirectly.

So, with export we have to consider two
collections of declarations and definitions -
one for the source file containing the
instantiation of the exported template (let's
call that the "instantiation file") and one
containing the definition of the exported
template (let's call that the "template
definition file").

During instantiation certain declarations
and definitions from the instantiation file
must "jump" to be made visible to the template
definition file and vice versa. My question
is, which definitions and declarations make
this jump?

Kind regards

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

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





Author: "Garry Lancaster" <glancaster@ntlworld.com>
Date: Wed, 6 Feb 2002 18:22:53 GMT
Raw View
Garry Lancaster:
> >C++ has got into problems when adding features
> >before anyone had implemented them. Ladies
> >and gentlemen, I give you "export"! (Though we shall
> >see, if the EDG and Comeau Computing's recent
> >claims are to be believed.) It's inherently a more
> >risky approach.

Greg Comeau:
> Perhaps in part, but saying this is not too strong, since it
> tends to put too much focus on one thing and one language.
>
> And as to what EDG and I are saying, where's the problem?
> If it matters any, a Comeau 4.3 beta is now available
> on our online compiler.

Looking back on what I wrote I can see it might
be interpreted as denigrating your efforts. That
wasn't my intention. I just used poor phrasing.

I am genuinely interested to see how you deal
with export. Unfortunately the online beta doesn't
answer the questions that most intrigue me
since it doesn't support multiple source files or
linking. I'll have to wait until I purchase a release
version.

To answer you question, the problem I have with
export is that I don't actually believe the C++ standard
gives me a coherent idea of what to expect from your
(or for that matter, any) implementation. I don't think
this problem would exist had a test implementation
of export been available prior to standardisation.

Kind regards

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

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





Author: comeau@panix.com (Greg Comeau)
Date: Thu, 7 Feb 2002 04:38:04 GMT
Raw View
In article <Ese88.1241$jL6.558877@news6-win.server.ntlworld.com>,
Garry Lancaster <glancaster@ntlworld.com> wrote:
>Garry Lancaster:
>> >C++ has got into problems when adding features
>> >before anyone had implemented them. Ladies
>> >and gentlemen, I give you "export"! (Though we shall
>> >see, if the EDG and Comeau Computing's recent
>> >claims are to be believed.) It's inherently a more
>> >risky approach.
>
>Greg Comeau:
>> Perhaps in part, but saying this is not too strong, since it
>> tends to put too much focus on one thing and one language.
>>
>> And as to what EDG and I are saying, where's the problem?
>> If it matters any, a Comeau 4.3 beta is now available
>> on our online compiler.
>
>Looking back on what I wrote I can see it might
>be interpreted as denigrating your efforts. That
>wasn't my intention. I just used poor phrasing.

Ok.

>I am genuinely interested to see how you deal
>with export. Unfortunately the online beta doesn't
>answer the questions that most intrigue me
>since it doesn't support multiple source files or
>linking. I'll have to wait until I purchase a release
>version.

Yes, and on this same note, this will need to be genuinely
addressed.  Actually, if folks have questions they want to
see addressed, they should post them either here or in email,
and I'll probably be glad to maintain a list (and their responses)
in some way, shape or form, either in the docs or in techtalk/templates,
realizing that it may not occur immediately.

>To answer you question, the problem I have with
>export is that I don't actually believe the C++ standard
>gives me a coherent idea of what to expect from your
>(or for that matter, any) implementation. I don't think
>this problem would exist had a test implementation
>of export been available prior to standardisation.

Of course.  But of course, this is chicken and egg'y too.
And comes back to my original point, that this is not
just an issue with a feature, or even with C++ per se,
but a general problem.  But I will concede that this one
does seem to be getting its share of issues.
--
Greg Comeau  GA BETA:4+ New Windows Backends  PLUS 'export' beta online!
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

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





Author: comeau@panix.com (Greg Comeau)
Date: Tue, 5 Feb 2002 16:57:11 GMT
Raw View
In article <Mjw38.6398$4i5.874795@news11-gui.server.ntli.net>,
Garry Lancaster <glancaster@ntlworld.com> wrote:
>C++ has got into problems when adding features
>before anyone had implemented them. Ladies
>and gentlemen, I give you "export"! (Though we shall
>see, if the EDG and Comeau Computing's recent
>claims are to be believed.) It's inherently a more
>risky approach.

Perhaps in part, but saying this is not too strong, since it
tends to put too much focus on one thing and one language.

And as to what EDG and I are saying, where's the problem?
If it matters any, a Comeau 4.3 beta is now available
on our online compiler.
--
Greg Comeau  GA BETA:4+ New Windows Backends  PLUS 'export' beta online!
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 22 Jan 2002 22:01:33 GMT
Raw View
(For sequence adaptor syntax suggest, see end of post.)

In article <3Gf38.1847$ka7.439395@news6-win.server.ntlworld.com>, "Garry
Lancaster" <glancaster@ntlworld.com> wrote:
>In practice a successful language cannot be all things
>to all people.

This is a commonly quoted dogma, and it seems it is often used in order to
prevent additions to the language that oneself believes one will not have
use for.

The ultimate is of course that everyone designs their own computer
languages (like me). :-)

> It must limit choices in order to stay a
>managable size. Otherwise you end up with a huge,
>bloated thing.

Not really; the main thing is that it is structured so that it easy for
users to orient themselves, plus that it is not puts a lot of burden on
the compiler implementors.

This is achieved by the generalization-specialization principle I mentioned.

>  I'm sure you're aware that some people
>already accuse C++ of this.

The problem with C++ is that it is unstructured, because it wanted to
ensure backwards compatibility, not that it is large in itself.

Therefore I believe that one should try to isolate a genuinely new C++
core that does not have the many problem of caused by the compatibility
attempts.

>> So the principle is already present in current C++.
>
>The compromise spirit I refer to is also present, I
>believe.

One should only introduce compromises when one is sure it is necessary.
Thus, try first try to structure the language, and do the compromises as
it is necessary.

Note that it is not even necessary that the theory describing the language
is implementable; this is an approach used by the LaTeX team: Once the
theory has been fixed, one implements a good approximation.

> This is why we have the proposal to make
>virtual dtors automatic for any class with one or
>more virtual functions. That's specifically aimed
>at a common novice mistake.

As for this example, I think the reason it is that it is hard to find
examples, as a matter of practical use, where the destructor should not be
virtual.

>> >This is also a good argument for using deque
>> >when you need push_front.
>
>> I do not make any such judgement of what programmer
>> X should use: I think that the stuff should be available
>> for the convenience of the programmers,
>> so that they intelligently can make their own choices.
>
>Not everyone has the luxury of refraining from judgement.
>Language and library designers must make choices
>about what will be included in their designs. Otherwise
>they'd never finish anything.

Much less today, in view of the more powerful computers.

Therefore, a well-structured library can be very large, if it only is easy
for users to orient themselves.

>> Memory has double every year the last few years,
>> so it means that slightly larger size in irrelevant for
>> most applications.

>I cringe when I hear this argument, or variants of
>it, used to justify a slower or more memory intensive
>option over a quicker and slimmer one. It's just so
>enticing, but if we choose the bloated option
>at every juncture we'd soon use up all these
>capacity increases and then some.

Not really: As computer capacity becomes cheaper, programmers time become
relatively more expensive. This pushes the structured programming,
followed by optimization in the cases needed.

In the case we are discussing, if the sequence interface is convenient to
the programmer, and it is easy to mix different sequence classes, then one
can have many hybrids in the code. So use the one you find is best for
your code, and do not worry about what others use.

>Personally, as my computer system acquires more
>memory I expect to be able to fit more useful stuff in it.

Well, that forces that the stuff is more structured. Also note the paradox
that the more capacity computers have, the more optimization one do.

So it does not necessarily mean that the code is more inefficient.

>std::vector::push_front's memory usage is still a
>demerit even if you believe that it's outweighed by
>its benefits.

I only noted that it was possible. I also noted that it is possible to
have many sequence hybrids.

>> Applications that need optimizations should have
>> specially designed classes for that.
>
>Trouble is, one man's optimizations are another man's
>anti-pessimizations. And who would really want a
>standard library that proudly boasted "zero optimizations"?
>(At least for general use.)

I don't think that STL is optimized, but only fairly efficient. In many
ways it is outright inefficient (like algorithms making unneeded
comparison caused by a theory built up around "<").

With say a sequence adaptor class, one might do a lot of optimizations.

>> So, from my point of view, it is a hunch derived from experience of
>> working with generalities: Strive for the general, if possible, and one
>> will avoid problems later.
>
>The danger with this approach in general is that
>you end up spending time coding something that is
>never going to be used. The Extreme Programming
>approach is actually the opposite - code for the
>specific problem, not the general case. If some
>other requirement comes up in the future, deal
>with it then, not before.

But here we are not speaking about solving a specific problem, but about
language design.

I figure that one starts with something more specific, and when one sees a
common structure, then one can and should generalize.

>It's pretty obvious that either dogma is wrong when
>taken to extremes. Compromise between competing
>requirements is again the key.

If one introduces a generality, then that must be possible to be
specialized to the old codes. This makes proper generalizations difficult.

So I do not think there is a big problem here: Generalization for its own
sake should be avoided.

But returning to the case at hand, perhaps one could have an adaptor
class, with X, Y sequence classes:
  template<class X>
  sequence {
  public:
    template
    sequence(const sequence<Y>&) { /* copy iterators */ }
    ...
  };
Then the various different sequence classes vector, list, deque, ... could
be used as sequence<vector<T> >, with the point that one gets copy
constructors
  sequence<vector<T> > a;
  sequence<list<T> > b;
  a = b;  // copies via iterators

A more natural syntax would be to view vector, list, deque as template
argument values, so that one would instead write
  sequence<T, vector> a;
  sequence<T, list> b;
  a = b;  // copies via iterators
But I haven't tried to figure out whether this is possible to implement in
current C++.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: "Garry Lancaster" <glancaster@ntlworld.com>
Date: Wed, 23 Jan 2002 11:49:07 CST
Raw View
Garry Lancaster:
> >In practice a successful language cannot be all things
> >to all people.

Hans Aberg:
> This is a commonly quoted dogma,...

Maybe that's because it's true.

> ... and it seems it is often used in order to
> prevent additions to the language that oneself believes one will not have
> use for.

There's nothing wrong with doing that - the fact
that you would never use a feature is good data -
provided one also gives others' opinions the
correct weight  when the time to make the
decision comes.

> The ultimate is of course that everyone designs their own computer
> languages (like me). :-)

I think every programmer eventually reaches
this stage if they persevere enough ;-)
What's your language called?

> > It must limit choices in order to stay a
> >managable size. Otherwise you end up with a huge,
> >bloated thing.
>
> Not really; the main thing is that it is structured so that it easy for
> users to orient themselves, plus that it is not puts a lot of burden on
> the compiler implementors.

> This is achieved by the generalization-specialization principle I
mentioned.

But the larger it is, the harder it is for
users to achieve this orientation, all other
things remaining equal.

And, as I pointed out, generalization-specialization
leaks, from a novice point of view. Another example
of this is when maintaining others' code, a common
novice assignment. They will come across lots of
stuff they don't understand if it was written by
someone further along the C++ trail.

> >  I'm sure you're aware that some people
> >already accuse C++ of this.
>
> The problem with C++ is that it is unstructured, because it wanted to
> ensure backwards compatibility, not that it is large in itself.
>
> Therefore I believe that one should try to isolate a genuinely new C++
> core that does not have the many problem of caused by the compatibility
> attempts.

I certainly view backwards compatibility with C
as a problem with C++ now (although I didn't
when I was first learning it).

> >> So the principle is already present in current C++.
> >
> >The compromise spirit I refer to is also present, I
> >believe.
>
> One should only introduce compromises when one is sure it is necessary.
> Thus, try first try to structure the language, and do the compromises as
> it is necessary.
>
> Note that it is not even necessary that the theory describing the language
> is implementable; this is an approach used by the LaTeX team: Once the
> theory has been fixed, one implements a good approximation.

C++ has got into problems when adding features
before anyone had implemented them. Ladies
and gentlemen, I give you "export"! (Though we shall
see, if the EDG and Comeau Computing's recent
claims are to be believed.) It's inherently a more
risky approach.

> > This is why we have the proposal to make
> >virtual dtors automatic for any class with one or
> >more virtual functions. That's specifically aimed
> >at a common novice mistake.
>
> As for this example, I think the reason it is that it is hard to find
> examples, as a matter of practical use, where the destructor should not be
> virtual.

As far as I know a virtual dtor will always work when
a non-virtual dtor would so there is no "should not"
case. People use non-virtual dtors as a space and
time optimization.

There are examples where there is no need for a
virtual dtor despite the presence of other virtual
functions though. COM is a good one because
the client never calls delete, the object always
calls delete this (or equivalent).

> >> >This is also a good argument for using deque
> >> >when you need push_front.
> >
> >> I do not make any such judgement of what programmer
> >> X should use: I think that the stuff should be available
> >> for the convenience of the programmers,
> >> so that they intelligently can make their own choices.
> >
> >Not everyone has the luxury of refraining from judgement.
> >Language and library designers must make choices
> >about what will be included in their designs. Otherwise
> >they'd never finish anything.
>
> Much less today, in view of the more powerful computers.

Always. In this sense no design is ever complete.

> Therefore, a well-structured library can be very large, if it
> only is easy for users to orient themselves.

> >> Memory has double every year the last few years,
> >> so it means that slightly larger size in irrelevant for
> >> most applications.
>
> >I cringe when I hear this argument, or variants of
> >it, used to justify a slower or more memory intensive
> >option over a quicker and slimmer one. It's just so
> >enticing, but if we choose the bloated option
> >at every juncture we'd soon use up all these
> >capacity increases and then some.
>
> Not really: As computer capacity becomes cheaper,
> programmers time become
> relatively more expensive. This pushes the structured programming,
> followed by optimization in the cases needed.

You refer, I think, to the general trend towards
higher level programming. Note that this happens
at a much slower pace than your "double every
year" or even than the more recognised Moore's
Law speed of doubling every 18 months.

> In the case we are discussing, if the sequence interface is convenient to
> the programmer, and it is easy to mix different sequence classes, then one
> can have many hybrids in the code. So use the one you find is best for
> your code, and do not worry about what others use.

> >Personally, as my computer system acquires more
> >memory I expect to be able to fit more useful stuff in it.
>
> Well, that forces that the stuff is more structured. Also note the paradox
> that the more capacity computers have, the more optimization one do.
>
> So it does not necessarily mean that the code is more inefficient.

Compilers that put the "oomph!" back are a good
thing, but why take it out in the first place?

[snip]

> >> Applications that need optimizations should have
> >> specially designed classes for that.
> >
> >Trouble is, one man's optimizations are another man's
> >anti-pessimizations. And who would really want a
> >standard library that proudly boasted "zero optimizations"?
> >(At least for general use.)
>
> I don't think that STL is optimized, but only fairly efficient.

Goes to prove what I said above (one man's optimizations
etc.)

Which STL are you using that you think is unoptimized?
Have you discussed additional optimizations with the
vendor?

> In many
> ways it is outright inefficient (like algorithms making unneeded
> comparison caused by a theory built up around "<").

You are free to replace the comparison function with
something else if you choose - it doesn't have to be
<. I'm sure you know this though - what's the real
issue that bothers you?

> With say a sequence adaptor class, one might do a lot of optimizations.
>
> >> So, from my point of view, it is a hunch derived from experience of
> >> working with generalities: Strive for the general, if possible, and one
> >> will avoid problems later.
> >
> >The danger with this approach in general is that
> >you end up spending time coding something that is
> >never going to be used. The Extreme Programming
> >approach is actually the opposite - code for the
> >specific problem, not the general case. If some
> >other requirement comes up in the future, deal
> >with it then, not before.
>
> But here we are not speaking about solving a specific problem, but about
> language design.
>
> I figure that one starts with something more specific, and when one sees a
> common structure, then one can and should generalize.

The problem is the same in language design as
in any other type of programming: when do you
stop generalising?

> >It's pretty obvious that either dogma is wrong when
> >taken to extremes. Compromise between competing
> >requirements is again the key.
>
> If one introduces a generality, then that must be possible to be
> specialized to the old codes. This makes proper generalizations difficult.

This seems to be impossible in general. I have seen
this referred to as the "abstraction cost". I understand
this as: any generalized implementation is inherently
less efficient than the ungeneralised implementation,
for at least one ungeneralised case. Don't ask me
to prove it formally, but I can't think of any counter-
examples.

> So I do not think there is a big problem here: Generalization for its own
> sake should be avoided.

Exactly my point. But as to when a design has reached
that point, that's a judgement call.

> But returning to the case at hand, perhaps one could have an adaptor
> class, with X, Y sequence classes:
>   template<class X>
>   sequence {
>   public:
>     template
>     sequence(const sequence<Y>&) { /* copy iterators */ }
>     ...
>   };
> Then the various different sequence classes vector, list, deque, ... could
> be used as sequence<vector<T> >, with the point that one gets copy
> constructors
>   sequence<vector<T> > a;
>   sequence<list<T> > b;
>   a = b;  // copies via iterators

If you want this, you are free to propose it to
the standards committee. But you need to justify
the real estate it occupies inside the library (the
implementation, testing and support costs) with
the benefits it provides.

> A more natural syntax would be to view vector, list, deque as template
> argument values, so that one would instead write
>   sequence<T, vector> a;
>   sequence<T, list> b;
>   a = b;  // copies via iterators
> But I haven't tried to figure out whether this is possible to implement in
> current C++.

template template arguments are allowed, so I don't
see why not, although I'm not sure any of my compilers
support them yet.

Kind regards

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

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 21 Jan 2002 17:29:45 GMT
Raw View
In article <l0c28.46257$WQ1.7582081@news6-win.server.ntlworld.com>, "Garry
Lancaster" <glancaster@ntlworld.com> wrote:
>> Well, I think that the languages should be built up around as general and
>> logically clear principles as possible, because that helps the user. Then
>> introduce compromises as needed in order to make the languages able to
>> produce efficient code.
...
>> As for generalities and abstractions, I think that people usually find
>> them difficult before having gotten used to them, but once they have done
>> they, they realize it is in fact more convenient, as it helps sorting out
>> the logical structures.
...
>That's a different sort of compromise than that needed in the
>design of language in order to balance it for both novice and
>expert use. I don't think this will ever go away.

I think that the core of the language should not have any such compromises
either: Instead some specialized components that are easy for the novice.

Thus, first strive for as general components as possible, then add
specialized components to that as need, and if possible, these should be
specialized from the general components.

The reason C++ is such a complex language is that this is not its history.
It has to live by its heritage, but one may isolate a new language
component that is simpler in its structure according to this principle.

>Is this bit of the thread becoming a bit too philosophical?

Not really, I recall that BS (se the first article in the thread C++0x
last year) announced that he wanted something like that. I have spoken
about this idea in this group, so I would be happy if have had some
influence on this matter.

But C++ already has such constructions, for example, the std::string and
std::iostream classes are specializations of more complex template
classes: These classes are what most novices would use. More specialized,
"expert" users, can design their own variations. But one should note that
the same person may be an "expert" in some circumstances and a "novice" in
other, and the language should reflect that fact in order to support it.

So the principle is already present in current C++.

>> It already is: operator new() typically reserves some memory at the
>> beginning, telling the size of the allocation. This part would only be
>> larger.
>
>Depends how you define "start of the allocation". I define
>it as the byte pointed to by the return value of the allocator's
>allocate() function. (Typically the same as operator new()'s
>return value.) That's certainly how vector sees it.

It is not a big point, as it is only a matter of implementation: I just
want to point out that there is nothing strange with hidden bits of
reserved memory hanging out also at the beginning, as the technique is
already in use.

>> All these new, more advanced container classes have
>> disadvantages; one realizes on the fact that faster computers
>> with ample memory can cope with that. Computer time and
>> space becomes increasingly cheaper, whereas human
>> programmer time becomes expensive.
>
>This is also a good argument for using deque
>when you need push_front.

I do not make any such judgement of what programmer X should use: I think
that the stuff should be available for the convenience of the programmers,
so that they intelligently can make their own choices.

>> >1. It will push the size of the typical implemention up
>> >slightly as there is an extra piece of information to track.
...
>> If you don't use push_front(), there is no change in the
>> behavior of vector.
>
>(1) still applies even if you never call push_front().

All this extra stuff depends on the fact that computers becomes more
powerful that it will make no difference.

Memory has double every year the last few years, so it means that slightly
larger size in irrelevant for most applications. Applications that need
optimizations should have specially designed classes for that.

Remember, that I did not say that a new vector class must have this
push_front feature, but I noted that it was possible. It is also by my
suggestion to have more sequence classes that are more specialized.

I explicitly said that I though it should be as easy as possible to start
with one sequence container class, and then switch to another, if some
optimizations needs to be done.

>> Otherwise, I do not know what variation to choose: I only noted
>> it seems possible to do it.
>
>Fair enough. All I'm noting is that the cost of
>doing so is non-zero.

So then the cost, after proper optimizations has been done by switching to
a better container class for your application is at least zero.

>> I think that if one only has copy constructors between sequential
>> container classes, like
>>   vector::vector<T, A1>(const list<T, A2>&);
>> where A1, A2 are different allocator classes, that would suffice.
>
>Thanks for clarifying what you meant. I must admit this isn't
>what I had in mind when I read your request for a single
>interface object with several implementations.
>
>I don't understand why one of the constructors that takes iterator
>arguments isn't suitable.

It is just that one tries to strive for a higher level more functional
interface. It easier for humans to cope with rather than having to write
out all details.

The same principle that makes one to add higher level structures to C++ in
the first place.

One usually numbs into these kind of questions when trying to design more
generic programming techniques, even though in the case at hand, I have no
good example of it.

So, from my point of view, it is a hunch derived from experience of
working with generalities: Strive for the general, if possible, and one
will avoid problems later.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: "Garry Lancaster" <glancaster@ntlworld.com>
Date: Tue, 22 Jan 2002 15:42:42 GMT
Raw View
Garry Lancaster:
> >That's a different sort of compromise than that needed in the
> >design of language in order to balance it for both novice and
> >expert use. I don't think this will ever go away.

Hans Aberg:
> I think that the core of the language should not have any such
> compromises either: Instead some specialized components
> that are easy for the novice.
>
> Thus, first strive for as general components as possible, then add
> specialized components to that as need, and if possible, these
> should be specialized from the general components.

> But C++ already has such constructions, for example, the std::string and
> std::iostream classes are specializations of more complex template
> classes: These classes are what most novices would use. More specialized,
> "expert" users, can design their own variations. But one should note that
> the same person may be an "expert" in some circumstances and a "novice" in
> other, and the language should reflect that fact in order to support it.

That sounds like the best of both worlds. But it isn't.

First, there's always some leakage from the expert's
view of the language to the novice's. (That's why they're
surprised when they try to forward declare class
std::string.)

In practice a successful language cannot be all things
to all people. It must limit choices in order to stay a
managable size. Otherwise you end up with a huge,
bloated thing. I'm sure you're aware that some people
already accuse C++ of this.

> So the principle is already present in current C++.

The compromise spirit I refer to is also present, I
believe. This is why we have the proposal to make
virtual dtors automatic for any class with one or
more virtual functions. That's specifically aimed
at a common novice mistake.

Hans Aberg:
> >> All these new, more advanced container classes have
> >> disadvantages; one realizes on the fact that faster computers
> >> with ample memory can cope with that. Computer time and
> >> space becomes increasingly cheaper, whereas human
> >> programmer time becomes expensive.

Garry Lancaster:
> >This is also a good argument for using deque
> >when you need push_front.

> I do not make any such judgement of what programmer
> X should use: I think that the stuff should be available
> for the convenience of the programmers,
> so that they intelligently can make their own choices.

Not everyone has the luxury of refraining from judgement.
Language and library designers must make choices
about what will be included in their designs. Otherwise
they'd never finish anything.

> >> >1. It will push the size of the typical implemention up
> >> >slightly as there is an extra piece of information to track.
> ...
> >> If you don't use push_front(), there is no change in the
> >> behavior of vector.
> >
> >(1) still applies even if you never call push_front().
>
> All this extra stuff depends on the fact that computers
> becomes more powerful that it will make no difference.
>
> Memory has double every year the last few years,
> so it means that slightly larger size in irrelevant for
> most applications.

I cringe when I hear this argument, or variants of
it, used to justify a slower or more memory intensive
option over a quicker and slimmer one. It's just so
enticing, but if we choose the bloated option
at every juncture we'd soon use up all these
capacity increases and then some.

Personally, as my computer system acquires more
memory I expect to be able to fit more useful stuff in it.

std::vector::push_front's memory usage is still a
demerit even if you believe that it's outweighed by
its benefits.

> Applications that need optimizations should have
> specially designed classes for that.

Trouble is, one man's optimizations are another man's
anti-pessimizations. And who would really want a
standard library that proudly boasted "zero optimizations"?
(At least for general use.)

[snip]

> So, from my point of view, it is a hunch derived from experience of
> working with generalities: Strive for the general, if possible, and one
> will avoid problems later.

The danger with this approach in general is that
you end up spending time coding something that is
never going to be used. The Extreme Programming
approach is actually the opposite - code for the
specific problem, not the general case. If some
other requirement comes up in the future, deal
with it then, not before.

It's pretty obvious that either dogma is wrong when
taken to extremes. Compromise between competing
requirements is again the key.

Kind regards

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

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





Author: Steve Clamage <clamage@eng.sun.com>
Date: Mon, 14 Jan 2002 19:55:25 GMT
Raw View
On Mon, 14 Jan 2002, Helmut Zeisel wrote:
>
> In what namespace will the
> standard library of ISO C++ 0x be?
>
> Will it still be in namespace std,
> or will there be a different namespace
> because of possible incompatibilities?

That is one of the issues the C++ committee needs to resolve.

We don't know what library incompatibilities there might be,
so we don't know to what extent namespace names would be an
issue. We also don't know whether using a new namespace name
would be a good solution to the problems we don't know about yet.

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

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 14 Jan 2002 21:22:20 GMT
Raw View
In article <Pine.SOL.4.33.0201141146080.20960-100000@taumet>, Steve
Clamage <clamage@eng.sun.com> wrote:
>> In what namespace will the
>> standard library of ISO C++ 0x be?

>> Will it still be in namespace std,
>> or will there be a different namespace
>> because of possible incompatibilities?

>That is one of the issues the C++ committee needs to resolve.
>
>We don't know what library incompatibilities there might be,
>so we don't know to what extent namespace names would be an
>issue. We also don't know whether using a new namespace name
>would be a good solution to the problems we don't know about yet.

One idea that comes to my mind, is to design an entirely new library, but
which is such that the old one can be implemented in terms of the new:
This will decrease the overhead for compiler designers, as they mainly
would need to make sure the new one if efficient. The old library can then
be supported by some generic sources, that defines it in terms of the old
one.

Under such circumstances, one might want the entirely new library be in a
new namespace.

I have mainly the STL library in my mind:

There I do not like the asymmetries. Specifically, I think the semi-open
interval [begin, end) paradigm is OK (a math generalization is semi-open
intervals of ordinals), but the rbegin() iterator should point at the last
container item, etc.

I would want to have more iterators: before, first, last, after. Then
begin = first, end = after. Then one should have rbegin = last, rend =
before.

Also, the class interfaces of the sequential containers should be the
same  as far as possible. (Like, list should have operator[], and for some
reason deque does not have reserve.) I also would want a tree based
sequential class added, with inserts and access in complexity O(log n).

I suggest that one unify the compare function and relational operator
stuff with a single compare function that can take the values { less,
equal, greater, unrelated }.

I have also noted that computer data types often need two relations: One
total, for use in sorting and associative containers (cutting down
searching/inserting time to logarithmic), and one other semantic one
(describing a semantic characteristic of the data type). So it would be
good if a library would be designed to catch that fact.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: helmut.zeisel@aon.at (Helmut Zeisel)
Date: Mon, 14 Jan 2002 22:27:23 GMT
Raw View
Steve Clamage <clamage@eng.sun.com> wrote in message news:<Pine.SOL.4.33.0201141146080.20960-100000@taumet>...
> On Mon, 14 Jan 2002, Helmut Zeisel wrote:
> >
> > In what namespace will the
> > standard library of ISO C++ 0x be?
> >
> > Will it still be in namespace std,
> > or will there be a different namespace
> > because of possible incompatibilities?
>
> That is one of the issues the C++ committee needs to resolve.
>
> We don't know what library incompatibilities there might be,
> so we don't know to what extent namespace names would be an
> issue. We also don't know whether using a new namespace name
> would be a good solution to the problems we don't know about yet.

OK.

I expected, however, that the answer is "different namespace",
since I thought that namespaces were designed
to solve possible incompatibilities,
especially when these incompatibilites are not well understood.

Helmut

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





Author: Pete Becker <petebecker@acm.org>
Date: Tue, 15 Jan 2002 06:46:54 GMT
Raw View
Helmut Zeisel wrote:
>
> Steve Clamage <clamage@eng.sun.com> wrote in message news:<Pine.SOL.4.33.0201141146080.20960-100000@taumet>...
> > On Mon, 14 Jan 2002, Helmut Zeisel wrote:
> > >
> > > In what namespace will the
> > > standard library of ISO C++ 0x be?
> > >
> > > Will it still be in namespace std,
> > > or will there be a different namespace
> > > because of possible incompatibilities?
> >
> > That is one of the issues the C++ committee needs to resolve.
> >
> > We don't know what library incompatibilities there might be,
> > so we don't know to what extent namespace names would be an
> > issue. We also don't know whether using a new namespace name
> > would be a good solution to the problems we don't know about yet.
>
> OK.
>
> I expected, however, that the answer is "different namespace",
> since I thought that namespaces were designed
> to solve possible incompatibilities,
> especially when these incompatibilites are not well understood.
>

Another approach is to not introduce incompatibilities. Library writers
are pretty good at this.

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

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





Author: "Jim Barry" <jim.barry@bigfoot.com>
Date: Tue, 15 Jan 2002 15:08:14 GMT
Raw View
Hans Aberg wrote:
> There I do not like the asymmetries. Specifically, I think
> the semi-open interval [begin, end) paradigm is OK (a math
> generalization is semi-open intervals of ordinals), but the
> rbegin() iterator should point at the last container item

But the iterator returned by rbegin() *does* give the last container
item when dereferenced. Somehow I don't think Stepanov and Lee were
taking stupid pills the day they invented reverse_iterator. (There is no
one-past-the-beginning.)

> list should have operator[]

Would you really use it?

> and for some reason deque does not have reserve.

It doesn't need it, because it's not expensive to increase the size of a
deque in the same way as it is with vector.

- Jim

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





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 15 Jan 2002 15:09:21 GMT
Raw View
Helmut Zeisel wrote:
>
> Steve Clamage <clamage@eng.sun.com> wrote in message news:<Pine.SOL.4.33.0201141146080.20960-100000@taumet>...
...
> > We don't know what library incompatibilities there might be,
> > so we don't know to what extent namespace names would be an
> > issue. We also don't know whether using a new namespace name
> > would be a good solution to the problems we don't know about yet.
>
> OK.
>
> I expected, however, that the answer is "different namespace",
> since I thought that namespaces were designed
> to solve possible incompatibilities,
> especially when these incompatibilites are not well understood.

Yes, but backwards compatiblity is also an issue. There's a number of
different ways to create a new namespace, while continuing support for
an old one. In fact, that's part of the problem: which of those ways
should be used? At this point it's premature to be inventing a solution
to a problem that's not yet been identified.

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





Author: Michiel.Salters@cmg.nl (Michiel Salters)
Date: Tue, 15 Jan 2002 15:15:28 GMT
Raw View
remove.haberg@matematik.su.se (Hans Aberg) wrote in message news:<remove.haberg-1401022150060001@du133-226.ppp.su-anst.tninet.se>...

> I have mainly the STL library in my mind:
>
> There I do not like the asymmetries. Specifically, I think the semi-open
> interval [begin, end) paradigm is OK (a math generalization is semi-open
> intervals of ordinals), but the rbegin() iterator should point at the last
> container item, etc.
>
> I would want to have more iterators: before, first, last, after. Then
> begin = first, end = after. Then one should have rbegin = last, rend =
> before.

It will be confusing to newbies that [first,last) misses one element.
Having a function BidirectionalIterator before(BidirectionalIterator);
might be useful though.

> Also, the class interfaces of the sequential containers should be the
> same  as far as possible. (Like, list should have operator[], and for some
> reason deque does not have reserve.) I also would want a tree based
> sequential class added, with inserts and access in complexity O(log n).

I think the complexity of Container::operator@ should be present only
if efficient. As far as orthogonality goes: Should list have a reserve,
too? What should it do?
Should vector have a member sort?

> I have also noted that computer data types often need two relations: One
> total, for use in sorting and associative containers (cutting down
> searching/inserting time to logarithmic), and one other semantic one
> (describing a semantic characteristic of the data type). So it would be
> good if a library would be designed to catch that fact.

You mean, like the STL now has with Predicate ? I think that's one
aspect very like not to change.

BTW, if you'd like e.g. a tree-based sequential class in the new
standard, the best way is to submit such a class - with
documentation and a possible implementation - to the C++ committee.
Waiting for the committee to write one is much less effective.

Regards,

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 16 Jan 2002 15:59:01 GMT
Raw View
In article <2bM08.21713$_x4.3258301@news2-win.server.ntlworld.com>, "Jim
Barry" <jim.barry@bigfoot.com> wrote:
>> There I do not like the asymmetries. Specifically, I think
>> the semi-open interval [begin, end) paradigm is OK (a math
>> generalization is semi-open intervals of ordinals), but the
>> rbegin() iterator should point at the last container item
>
>But the iterator returned by rbegin() *does* give the last container
>item when dereferenced.

As we all know. :-)

> Somehow I don't think Stepanov and Lee were
>taking stupid pills the day they invented reverse_iterator.

Just because something is clever, it does not mean that it is correct for
use (also see below).

> (There is no
>one-past-the-beginning.)

I proposed there should be one such "before" pointer. The reason there is
none is probably because of the C array legacy, where no pointer before
can be guaranteed, rather than any attempts at making a smart library
design.

But on most computers it is possible with a "before" pointer, and it
should be possible for the C++ compiler writer to solve this issue. So it
seems not worth letting the old C legacy influence the structure of the
whole library.

>> list should have operator[]
>
>Would you really use it?

That (by actual use) is how I discovered it:

If one does not know from the beginning which container is right, it is
natural to start use one, and then switch to another.

>> and for some reason deque does not have reserve.
>
>It doesn't need it, because it's not expensive to increase the size of a
>deque in the same way as it is with vector.

I discovered this one when writing a C++ skeleton file for the GNU Bison
parser generator, where one can switch between containers for use with its
stack: Then one wants a syntactically common interface, in order to avoid
having to throw in lots of extra macros.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 16 Jan 2002 15:59:42 GMT
Raw View
In article <cefd6cde.0201150317.10109223@posting.google.com>,
Michiel.Salters@cmg.nl (Michiel Salters) wrote:
>> I would want to have more iterators: before, first, last, after. Then
>> begin = first, end = after. Then one should have rbegin = last, rend =
>> before.
>
>It will be confusing to newbies that [first,last) misses one element.

C++ is not the language for C++ beginners alone (or is it :-) )?

In many situations though, one wants inexpensive access to the last iterator.

>> Also, the class interfaces of the sequential containers should be the
>> same  as far as possible. (Like, list should have operator[], and for some
>> reason deque does not have reserve.) I also would want a tree based
>> sequential class added, with inserts and access in complexity O(log n).
>
>I think the complexity of Container::operator@ should be present only
>if efficient.

The thing is that on a modern computer one should really determine which
container to use by using a profiler. For example, it may still be
efficient to use operator--() on a forward singly linked list if it is not
invoked often.

Then it should be easy to switch between containers.

> As far as orthogonality goes: Should list have a reserve,
>too? What should it do?

It may depend on implementations: Lists implement links by using operator
new(), which is slow on most computers. Thus, one may want to optimize by
throwing in a reserve() at a time when the computer has nothing better to
do.

>Should vector have a member sort?

Isn't the time complexity gonna be the same, but with the difference that
copy constructors are invoked instead of re-linking?

It depends on what dogma you adhere to: If, as I proposed, the containers
are viewed as semantically the same, but with different complexities, then
it should.

If the idea is that only those operations should be present that are
believed to be efficient, then it should not.

But if sorting is done rarely, and random access a lot, it may still be
more efficient to use a vector class. Then the C++ programmer have to make
a separate implementation (digging into the STL library or something): It
is convenient to have it present in the class interface, as one then knows
where to find it.

The C++ standards costs just $18, so one can assume that programmers read
it. So, by that, it should be possible to allow less efficient operations,
by merely assuming people checking the docs of the standard.

>> I have also noted that computer data types often need two relations: One
>> total, for use in sorting and associative containers (cutting down
>> searching/inserting time to logarithmic), and one other semantic one
>> (describing a semantic characteristic of the data type). So it would be
>> good if a library would be designed to catch that fact.
>
>You mean, like the STL now has with Predicate ? I think that's one
>aspect very like not to change.

I am no sure what you mean here: STL has usually two ways to get hold of
the comparison needed, either via an operator<() or a compare function,
expressing the same thing. Then I think that both those should be replaced
with a single compare function taking values { less, equal, greater,
unrelated }; operator< etc would expand to that one.

Then there arises a different question: For this to work on the
containers, in some types of sorting (like binary search), etc., the order
needs to be total. If one already has defined comparison function that is
total, then that one can be used of course. But if it is not, or has not
been defined, then one might still use the containers if C++ somehow
supported a total order:

One frequently asked request is that C++ supports such a default order in
classes, as is done in some languages: Basically, one takes the
lexicographical order on the data, with a possibility to customize it.

Then one still has the benefit of improved complexities even though the
data types do not have natural total orders.

>BTW, if you'd like e.g. a tree-based sequential class in the new
>standard, the best way is to submit such a class - with
>documentation and a possible implementation - to the C++ committee.
>Waiting for the committee to write one is much less effective.

Perhaps: I think though that it can be easily extracted from the tree
class usually used to implement the associative containers. So anybody
into that stuff could easily write that class, I think.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: "Garry Lancaster" <glancaster@ntlworld.com>
Date: Wed, 16 Jan 2002 17:42:07 GMT
Raw View
Michiel Salters:
> > As far as orthogonality goes: Should list have a reserve,
> >too? What should it do?

Hans Aberg:
> It may depend on implementations: Lists implement links
> by using operator new(), which is slow on most computers.
> Thus, one may want to optimize by throwing in a reserve()
> at a time when the computer has nothing better to do.
>
> >Should vector have a member sort?
>
> Isn't the time complexity gonna be the same, but with the difference that
> copy constructors are invoked instead of re-linking?
>
> It depends on what dogma you adhere to: If, as I proposed, the containers
> are viewed as semantically the same, but with different complexities, then
> it should.
>
> If the idea is that only those operations should be present that are
> believed to be efficient, then it should not.
>
> But if sorting is done rarely, and random access a lot, it may still be
> more efficient to use a vector class. Then the C++ programmer have to make
> a separate implementation (digging into the STL library or something): It
> is convenient to have it present in the class interface, as one then knows
> where to find it.

How far would you be prepared to go to aid orthogonality?
Would you add push_front to vector for instance? I mention
that because I find your requests for reserve on list and
sort on vector semi-reasonable, but I would draw the line
at push_front for vector. The complexity is just too awful to
bear - having it as part of the interface will just encourage
people to call it ;-)

There are other problems with container orthogonality:

1. How to make associative containers behave like
the sequence ones.

2. How to make vector as exception safe as list.

3. Different iterator invalidation effects.

While orthogonality is a fine goal, it cannot be achieved for
the standard containers. You might make the callable
interfaces identical, at least for the sequence containers,
but there's more to the contract between client and class
than that. There's no IS-A relationship between any two of
the container class templates and it would be misleading
to pretend that there was.

You can find the orthogonality you seek elsewhere though
- in the iterator classes.

Kind regards

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

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Thu, 17 Jan 2002 16:12:54 GMT
Raw View
In article <rFi18.29483$Hg7.3010771@news11-gui.server.ntli.net>, "Garry
Lancaster" <glancaster@ntlworld.com> wrote:
>There are other problems with container orthogonality:
>
>1. How to make associative containers behave like
>the sequence ones.

To begin with, one should never forcibly try to make classes with
essentially different semantics look alike. So (multi-) set/map are all
semantically different and also different from the sequential containers,
and should be kept like that.

>2. How to make vector as exception safe as list.
>
>3. Different iterator invalidation effects.

I am not sure about those issues.

One idea that comes to my mind though is to introduce a new array class
which is more lightweight. Then the vector class is enhanced to be more
like that list, deque end the eventual tree class.

The array class would then be deliberately given a special semantics,
reflecting the fact that is mainly to be used in time/space critical
replacements of the C arrays.

>How far would you be prepared to go to aid orthogonality?
>Would you add push_front to vector for instance?
...
> The complexity is just too awful to
>bear - having it as part of the interface will just encourage
>people to call it ;-)

You have to make up your mind: Either use the dogma to serve the prudent
programmer, or take the view that the programmers are newbies that really
cannot handle this kind of things. Perhaps one should introduce a new
namespace "dork" where all this simplified stuff can be put. :-)

> I mention
>that because I find your requests for reserve on list and
>sort on vector semi-reasonable, but I would draw the line
>at push_front for vector.

The way it is implemented now, you mean: push_back typically doubles the
memory, leaving the reserved memory at the back. push_front would have to
the same, leaving the memory at the front.

>...You might make the callable
>interfaces identical, at least for the sequence containers,
>but there's more to the contract between client and class
>than that. There's no IS-A relationship between any two of
>the container class templates and it would be misleading
>to pretend that there was.

One could have copy-constructors between different types of sequence
containers. But I do not know how to implement that in a good way in
current C++:

It seems to be a weakness of current C++ that it is hard to implement a
single interface object which may have several different implementations.
I have encountered this problem when for example implementing calenders:
Each new calender is just another form of representing time, and one
should then able to have good automatic conversions between the calenders.
But it proved difficult to implement that.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: Christopher Eltschka <celtschk@web.de>
Date: Thu, 17 Jan 2002 17:13:57 GMT
Raw View
remove.haberg@matematik.su.se (Hans Aberg) writes:

> In article <Pine.SOL.4.33.0201141146080.20960-100000@taumet>, Steve
> Clamage <clamage@eng.sun.com> wrote:
> >> In what namespace will the
> >> standard library of ISO C++ 0x be?
>
> >> Will it still be in namespace std,
> >> or will there be a different namespace
> >> because of possible incompatibilities?
>
> >That is one of the issues the C++ committee needs to resolve.
> >
> >We don't know what library incompatibilities there might be,
> >so we don't know to what extent namespace names would be an
> >issue. We also don't know whether using a new namespace name
> >would be a good solution to the problems we don't know about yet.
>
> One idea that comes to my mind, is to design an entirely new library, but
> which is such that the old one can be implemented in terms of the new:
> This will decrease the overhead for compiler designers, as they mainly
> would need to make sure the new one if efficient. The old library can then
> be supported by some generic sources, that defines it in terms of the old
> one.
>
> Under such circumstances, one might want the entirely new library be in a
> new namespace.
>
> I have mainly the STL library in my mind:
>
> There I do not like the asymmetries. Specifically, I think the semi-open
> interval [begin, end) paradigm is OK (a math generalization is semi-open
> intervals of ordinals), but the rbegin() iterator should point at the last
> container item, etc.

All if this stuff gets pretty intuitive as soon as you view the
iterators as pointing _between_ the elements and accessing the element
on the right hand side.

For example, if your sequence looks like

   +---+---+---+---+
   | 1 | 2 | 3 | 4 |
   +---+---+---+---+
   ^               ^
   |               |
 begin            end

you have element 1 after begin, and nothing after end. There's no
"one-past-end", which would have to point into the white space after
the sequence. And the only assymmetry is the "access to the right"
rule, for which there's no "access to the left" analog.

If you reverse it (think of a slide you look at from the back side),
you get

   +---+---+---+---+
   | 4 | 3 | 2 | 1 |
   +---+---+---+---+
   ^               ^
   |               |
  dne            nigeb
 rbegin          rend

Now, on the right hand side of rbegin is the 4, and on the right hand
side of rend is nothing. Of course, rbegin still points to the same
point as end, not "one apart".

Also the "one past end" problem is immediatly gone (you see, there is
no "one past end" item in the sequence).

If you introduce an iterator in the middle of the original sequence,
you get

   +---+---+---+---+
   | 1 | 2 | 3 | 4 |
   +---+---+---+---+
   ^       ^       ^
   |       |       |
 begin    mid     end

You see immediatly that the item you access through mid (i.e. the item
on the right hand side of mid) is not in the sequence from begin to
mid, but is the first one of the sequence from mid to end.

Now let's insert a new item at mid. Where does it appear? Well,
there's no doubt:

   +---+---+---+---+---+
   | 1 | 2 | 5 | 3 | 4 |
   +---+---+---+---+---+

The only question is, if the iterator is not invalidated by the insert
(as it is f.ex. in vectors), where should it point? Well, if inserting
a sequence element by element should work, there's only one position:
beween 5 and 3, i.e. _after_ the newly inserted element. That is, the
new element is inserted before mid:

   +---+---+---+---+---+
   | 1 | 2 | 5 | 3 | 4 |
   +---+---+---+---+---+
   ^           ^       ^
   |           |       |
 begin        mid     end

>
> I would want to have more iterators: before, first, last, after. Then
> begin = first, end = after. Then one should have rbegin = last, rend =
> before.

With the in-between interpretation of iterators (which really clears
up a lot of otherwise strange things in STL) this does not make
sense. There's no one-past-end (the end iterator really points to the
end of the sequence).

The only thing one could think of is to introduce member functions
right() (equivalent to operator*) and left() (to access the member on
the left hand side) for bidirectional iterators (the names could of
course also be different, say "before" and "after"). Then everything
would be symmetric (for bidirectional iterators; forward iterators and
below certainly cannot be symmetric).

[...]

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





Author: "Garry Lancaster" <glancaster@ntlworld.com>
Date: Thu, 17 Jan 2002 18:25:14 GMT
Raw View
Garry Lancaster:
> >There are other problems with container orthogonality:
> >
> >1. How to make associative containers behave like
> >the sequence ones.

Hans Aberg:
> To begin with, one should never forcibly try to make classes with
> essentially different semantics look alike. So (multi-) set/map are all
> semantically different and also different from the sequential containers,
> and should be kept like that.

OK.

> >2. How to make vector as exception safe as list.
> >
> >3. Different iterator invalidation effects.
>
> I am not sure about those issues.
>
> One idea that comes to my mind though is to introduce a new array class
> which is more lightweight. Then the vector class is enhanced to be more
> like that list, deque end the eventual tree class.
>
> The array class would then be deliberately given a special semantics,
> reflecting the fact that is mainly to be used in time/space critical
> replacements of the C arrays.

Do you mean like boost::array?

> >How far would you be prepared to go to aid orthogonality?
> >Would you add push_front to vector for instance?
> ...
> > The complexity is just too awful to
> >bear - having it as part of the interface will just encourage
> >people to call it ;-)
>
> You have to make up your mind: Either use the dogma to serve the prudent
> programmer, or take the view that the programmers are newbies that really
> cannot handle this kind of things. Perhaps one should introduce a new
> namespace "dork" where all this simplified stuff can be put. :-)

I disagree - we don't have to choose between two extreme
positions. Compromise is the key.

Realistically, we have to serve both the newbies and the experts,
albeit with the balance tilted more to the experts than many other
languages, and we have to find a solution that is reasonably useful
for both. Look at it the other way round - with the *current* library
the ease of doing something to a container is roughly related to
the chances that someone needs to do it. This helps newbies.
Experts should have no problems sorting vectors or even grabbing
memory for list items in advance. As far as pre-allocating list items,
newbies won't need to do it. As far as sorting vectors, the logic is,
I admit, not so strong, but maybe it will encourage them to read
up on *why* vector has no sort but list does.

> > I mention
> >that because I find your requests for reserve on list and
> >sort on vector semi-reasonable, but I would draw the line
> >at push_front for vector.
>
> The way it is implemented now, you mean: push_back typically doubles the
> memory, leaving the reserved memory at the back. push_front would have to
> the same, leaving the memory at the front.

If I understand your proposal correctly it would mean
that the obvious implementation of vector would have
to change because the first real item of vector's
underlying array would no longer be the same as the
start of the allocation.

This is certainly better than the naive push_front I had
envisaged, but I can see a number of disadvantage:

1. It will push the size of the typical implemention up
slightly as there is an extra piece of information to track.

2. More wasted memory when calls to push_front and
push_back are mixed. Off the top of my head I think the
average amount of wasted memory would double.

I don't think either of these are killers, but I'm afraid I
still don't think vector::push_front is worth it. It's certainly
not something that you can add for free and has been
left out purely because the committee were in a restrictive
frame of mind when they formalised it. I'd be
interested to thing what any standard library
implementers or power users think about it though.

> >...You might make the callable
> >interfaces identical, at least for the sequence containers,
> >but there's more to the contract between client and class
> >than that. There's no IS-A relationship between any two of
> >the container class templates and it would be misleading
> >to pretend that there was.
>
> One could have copy-constructors between different types of sequence
> containers. But I do not know how to implement that in a good way in
> current C++:

I'd use iterators to copy between containers. That's well
supported.

> It seems to be a weakness of current C++ that it is hard to implement a
> single interface object which may have several different implementations.

Perhaps a concrete example would be helpful here (something
more tangible than the brief calendar description I snipped)
because I wouldn't say this was "hard" in C++. Nor would I
say it was "easy". It's a medium level task, well covered by the
"Design Patterns" book.

[snip]

Kind regards

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

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





Author: cmd@gmrc.gecm.com (Chris Dearlove)
Date: Fri, 18 Jan 2002 11:06:42 CST
Raw View
Hans Aberg (remove.haberg@matematik.su.se) wrote:
: One could have copy-constructors between different types of sequence
: containers. But I do not know how to implement that in a good way in
: current C++:

See Scott Meyers' Essential STL Item 5. (In short each container has a
constructor taking two iterators as parameters.)

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





Author: Michiel.Salters@cmg.nl (Michiel Salters)
Date: Fri, 18 Jan 2002 11:50:24 CST
Raw View
remove.haberg@matematik.su.se (Hans Aberg) wrote in message news:<remove.haberg-1601021336220001@du131-226.ppp.su-anst.tninet.se>...
> In article <cefd6cde.0201150317.10109223@posting.google.com>,
> Michiel.Salters@cmg.nl (Michiel Salters) wrote:
> >> I would want to have more iterators: before, first, last, after. Then
> >> begin = first, end = after. Then one should have rbegin = last, rend =
> >> before.
> >
> >It will be confusing to newbies that [first,last) misses one element.
>
> C++ is not the language for C++ beginners alone (or is it :-) )?

No it isn't. But experts can do without .last(), so who benefits ?

> In many situations though, one wants inexpensive access to the last iterator.

You mean, .rbegin() ?

> >> Also, the class interfaces of the sequential containers should be the
> >> same  as far as possible. (Like, list should have operator[], and for some
> >> reason deque does not have reserve.) I also would want a tree based
> >> sequential class added, with inserts and access in complexity O(log n).
> >
> >I think the complexity of Container::operator@ should be present only
> >if efficient.
>
> The thing is that on a modern computer one should really determine which
> container to use by using a profiler. For example, it may still be
> efficient to use operator--() on a forward singly linked list if it is not
> invoked often.

Invoking slist::iterator slist_before(slist::iterator) is just as efficient,
not a trap for newbies, and shows clearly in code that the operation isn't
a simple one. And since it's by your definition rare, the extra characters
aren't the problem either.

> > As far as orthogonality goes: Should list have a reserve,
> >too? What should it do?
>
> It may depend on implementations: Lists implement links by using operator
> new(), which is slow on most computers. Thus, one may want to optimize by
> throwing in a reserve() at a time when the computer has nothing better to
> do.

Factually wrong; std::list implements links by using std::allocator,
which reserves larger blocks at a time. vector<> can't benefit as much
as list because vector<> uses a single large block which must be copied
on resizing. Reserve prevents copies due to resizing, that's why it's
more efficient.

> >Should vector have a member sort?
>
> Isn't the time complexity gonna be the same, but with the difference that
> copy constructors are invoked instead of re-linking?

?

> It depends on what dogma you adhere to: If, as I proposed, the containers
> are viewed as semantically the same, but with different complexities, then
> it should.
>
> If the idea is that only those operations should be present that are
> believed to be efficient, then it should not.

"believed to be efficient" could be insulting to some. The point is
not belief of efficiency, but proof of complexity.

> But if sorting is done rarely, and random access a lot, it may still be
> more efficient to use a vector class. Then the C++ programmer have to make
> a separate implementation (digging into the STL library or something): It
> is convenient to have it present in the class interface, as one then knows
> where to find it.

Actually, I think this is a good point for moving list::sort() to
algorithm and renaming it list_sort. Quoting Scott: Prefer "non-members."

> The C++ standards costs just $18, so one can assume that programmers read
> it. So, by that, it should be possible to allow less efficient operations,
> by merely assuming people checking the docs of the standard.

The cost isn't the issue. The thing is almost unreadable.

> >> I have also noted that computer data types often need two relations: One
> >> total, for use in sorting and associative containers (cutting down
> >> searching/inserting time to logarithmic), and one other semantic one
> >> (describing a semantic characteristic of the data type). So it would be
> >> good if a library would be designed to catch that fact.
> >
> >You mean, like the STL now has with Predicate ? I think that's one
> >aspect very like not to change.
>
> I am no sure what you mean here: STL has usually two ways to get hold of
> the comparison needed, either via an operator<() or a compare function,
> expressing the same thing. Then I think that both those should be replaced
> with a single compare function taking values { less, equal, greater,
> unrelated }; operator< etc would expand to that one.

Now you really got me confused. First you mention two orderings, and
now a single comparison function ?

> >BTW, if you'd like e.g. a tree-based sequential class in the new
> >standard, the best way is to submit such a class - with
> >documentation and a possible implementation - to the C++ committee.
> >Waiting for the committee to write one is much less effective.
>
> Perhaps: I think though that it can be easily extracted from the tree
> class usually used to implement the associative containers. So anybody
> into that stuff could easily write that class, I think.

Could, perhaps. Wants, less likely, given that I haven't noticed such
a proposal.

Regards,
--
Michiel Salters

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Fri, 18 Jan 2002 11:52:39 CST
Raw View
In article <4EE18.35732$Hg7.3651609@news11-gui.server.ntli.net>, "Garry
Lancaster" <glancaster@ntlworld.com> wrote:
>> One idea that comes to my mind though is to introduce a new array class
>> which is more lightweight. Then the vector class is enhanced to be more
>> like that list, deque end the eventual tree class.

>> The array class would then be deliberately given a special semantics,
>> reflecting the fact that is mainly to be used in time/space critical
>> replacements of the C arrays.

>Do you mean like boost::array?

I haven't seen this; but if it already exists, then by adding it would
enable one to make the vector class more secure.

>> You have to make up your mind: Either use the dogma to serve the prudent
>> programmer, or take the view that the programmers are newbies that really
>> cannot handle this kind of things. Perhaps one should introduce a new
>> namespace "dork" where all this simplified stuff can be put. :-)
>
>I disagree - we don't have to choose between two extreme
>positions. Compromise is the key.

Well, I think that the languages should be built up around as general and
logically clear principles as possible, because that helps the user. Then
introduce compromises as needed in order to make the languages able to
produce efficient code.

But as compilers get more sophisticated, the less compromise is needed.

As for generalities and abstractions, I think that people usually find
them difficult before having gotten used to them, but once they have done
they, they realize it is in fact more convenient, as it helps sorting out
the logical structures.

In practical terms, it help should cutting down on the need to consult the
standard. Instead one programs around the more general concepts, which are
easy to remember, and at the time for optimization or the nitty gritty
details, one goes in checking just those details.

>> The way it is implemented now, you mean: push_back typically doubles the
>> memory, leaving the reserved memory at the back. push_front would have to
>> the same, leaving the memory at the front.
>
>If I understand your proposal correctly it would mean
>that the obvious implementation of vector would have
>to change because the first real item of vector's
>underlying array would no longer be the same as the
>start of the allocation.

It already is: operator new() typically reserves some memory at the
beginning, telling the size of the allocation. This part would only be
larger.

>This is certainly better than the naive push_front I had
>envisaged, but I can see a number of disadvantage:

All these new, more advanced container classes have disadvantages; one
realizes on the fact that faster computers with ample memory can cope with
that. Computer time and space becomes increasingly cheaper, whereas human
programmer time becomes expensive.

>1. It will push the size of the typical implemention up
>slightly as there is an extra piece of information to track.
>
>2. More wasted memory when calls to push_front and
>push_back are mixed. Off the top of my head I think the
>average amount of wasted memory would double.

Clearly, those are disadvantages that one would deliberately choose in
order to ensure a good time complexity, just as in the case of
push_back().

>I don't think either of these are killers, but I'm afraid I
>still don't think vector::push_front is worth it.

If you don't use push_front(), there is no change in the behavior of vector.

Otherwise, I do not know what variation to choose: I only noted it seems
possible to do it.

>> It seems to be a weakness of current C++ that it is hard to implement a
>> single interface object which may have several different implementations.
>
>Perhaps a concrete example would be helpful here (something
>more tangible than the brief calendar description I snipped)

I think that if one only has copy constructors between sequential
container classes, like
  vector::vector<T, A1>(const list<T, A2>&);
where A1, A2 are different allocator classes, that would suffice.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Fri, 18 Jan 2002 11:52:45 CST
Raw View
In article <a26vg3$bhe$1@news.tuwien.ac.at>, Christopher Eltschka
<celtschk@web.de> wrote:
>All if this stuff gets pretty intuitive as soon as you view the
>iterators as pointing _between_ the elements and accessing the element
>on the right hand side.

I recall that once I classified iterators this way:

For reads/write over, the iterators should point at the object, but for
inserts in between. If it points at an iterator, an insert needs an
additional {before, after} label. As total, an iterator for write/insert
may have a label {before, at, after}. In addition, an iterator has a
direction {forward, reverse}, which an "automatically stepping iterators",
as used by files, is applied after the read\write/insert operation.

With this additional iterator classification, one can say that STL
associates before <-> reverse, and after <-> forward.

But is possible to further unify container iterators and file iterators
(pointers) by this classification).

>The only question is, if the iterator is not invalidated by the insert
>(as it is f.ex. in vectors), where should it point?

For erase, one {before, at, after}, telling where it should point after
the erase. When using the "at" variation, it would become invalidated; one
would have this variation because of efficiency reasons (stepping takes
time, if it is not needed, and cannot be optimized away by the compiler).

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Fri, 18 Jan 2002 12:54:12 CST
Raw View
In article <a29j5j$fma$1@miranda.gmrc.gecm.com>,
chris.dearlove@baesystems.com wrote:
>: One could have copy-constructors between different types of sequence
>: containers. But I do not know how to implement that in a good way in
>: current C++:
>
>See Scott Meyers' Essential STL Item 5. (In short each container has a
>constructor taking two iterators as parameters.)

This one I of course know. But I am speaking about higher level language
constructs: constructors
  vector::vector<T, A1>(const list<T, A2>&);
for different allocators A1, A2.

If one has a small set of containers { vector, list, deque, tree } then
one can do that for each class knowing each other class. But suppose one
wants to add more containers, then this become increasingly more job to
do.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Fri, 18 Jan 2002 13:24:19 CST
Raw View
In article <cefd6cde.0201180105.3d379b29@posting.google.com>,
Michiel.Salters@cmg.nl (Michiel Salters) wrote:
>> C++ is not the language for C++ beginners alone (or is it :-) )?
>
>No it isn't. But experts can do without .last(), so who benefits ?

This sounds like an invitation for series of polemics: Do you know any
such expert? :-) Experts can probably program directly in machine code (or
C). :-) Etc.

I will pass this one. :-)

>> In many situations though, one wants inexpensive access to the last iterator.
>
>You mean, .rbegin() ?

rbegin() will typically take end() and make one step towards begin() when
dereferenced.

>> The thing is that on a modern computer one should really determine which
>> container to use by using a profiler. For example, it may still be
>> efficient to use operator--() on a forward singly linked list if it is not
>> invoked often.
>
>Invoking slist::iterator slist_before(slist::iterator) is just as efficient,
>not a trap for newbies, and shows clearly in code that the operation isn't
>a simple one. And since it's by your definition rare, the extra characters
>aren't the problem either.

The thing is that one does not take advantage of the efficient idea of a
class interface. If you want to indicate that it is not efficient, why not
add it to the class interface and add a macro
  #define not_efficient
Then you can write
  class slist {
    ...
    class iterator {
       not_efficient iterator& operator -- ()
      ...
    };
  };
and every newbie will see that.

The operation is then easy to find: in the class interface; one does not
have to go to the C++ standard to look for sporadic items.

>> >Should vector have a member sort?
>>
>> Isn't the time complexity gonna be the same, but with the difference that
>> copy constructors are invoked instead of re-linking?
>
>?

??

>> If the idea is that only those operations should be present that are
>> believed to be efficient, then it should not.
>
>"believed to be efficient" could be insulting to some. The point is
>not belief of efficiency, but proof of complexity.

So, what is the formula telling which functions with which complexity to
include in the class interface, and which functions that should be
accesses without the class interface via sporadic names?

>> But if sorting is done rarely, and random access a lot, it may still be
>> more efficient to use a vector class. Then the C++ programmer have to make
>> a separate implementation (digging into the STL library or something): It
>> is convenient to have it present in the class interface, as one then knows
>> where to find it.
>
>Actually, I think this is a good point for moving list::sort() to
>algorithm and renaming it list_sort. Quoting Scott: Prefer "non-members."

This is a though that also came to my mind: The container interface should
mainly contain operations fundamental to its semantics, not other types of
operations. (So perhaps we agrees on something.)

One exception would be if say a function in a multi-threaded environment
would need special treatment; then it should be added.

>> The C++ standards costs just $18, so one can assume that programmers read
>> it. So, by that, it should be possible to allow less efficient operations,
>> by merely assuming people checking the docs of the standard.
>
>The cost isn't the issue. The thing is almost unreadable.

The cost is certainly an issue, because before language standards where
available at a low cost, people would not buy them. Thus, actual language
reference would be low.

C++ is a complex language in part because it is multi-paradigm, and it is
not going to diminish: It needs to be augmented in various areas.

So if one should decrease the complexity to the user, the library should
be as far as possible restructured so that the stuff is where one expects
it. For example, if containers have the same semantic interface, give them
the same class interface, because there is what one would first look for
the stuff.

>> I am no sure what you mean here: STL has usually two ways to get hold of
>> the comparison needed, either via an operator<() or a compare function,
>> expressing the same thing. Then I think that both those should be replaced
>> with a single compare function taking values { less, equal, greater,
>> unrelated }; operator< etc would expand to that one.
>
>Now you really got me confused. First you mention two orderings, and
>now a single comparison function ?

STL uses two different ways to get hold of the ordering, I want to unify
them, if possible.

By contrast, it implicitly assumes each class by which the container class
only uses a single ordering. There I point out that one may need one
special total order for use with containers & sorting, whereas classes may
have a additional semantic order.

>> Perhaps: I think though that it can be easily extracted from the tree
>> class usually used to implement the associative containers. So anybody
>> into that stuff could easily write that class, I think.
>
>Could, perhaps. Wants, less likely, given that I haven't noticed such
>a proposal.

I proposed it in the C++0x thread recently, so perhaps nobody has given it
thought before. -- I have never seen such a construction anywhere; it just
seems me that in view of that one is already has balanced tree
implementations in the associative containers, one would get this one
almost for free.

So perhaps before people can decide whether they want or propose things,
it must first be invented.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

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





Author: "Garry Lancaster" <glancaster@ntlworld.com>
Date: Sat, 19 Jan 2002 10:50:01 CST
Raw View
Hans Aberg:
> >> You have to make up your mind: Either use the dogma to serve
> >> the prudent programmer, or take the view that the
> >> programmers are newbies that really cannot handle this kind
> >> of things. Perhaps one should introduce a new
> >> namespace "dork" where all this simplified stuff can be
> >> put. :-)

Garry Lancaster:
> >I disagree - we don't have to choose between two extreme
> >positions. Compromise is the key.
>
> Well, I think that the languages should be built up around as general and
> logically clear principles as possible, because that helps the user. Then
> introduce compromises as needed in order to make the languages able to
> produce efficient code.
>
> But as compilers get more sophisticated, the less compromise is needed.
>
> As for generalities and abstractions, I think that people usually find
> them difficult before having gotten used to them, but once they have done
> they, they realize it is in fact more convenient, as it helps sorting out
> the logical structures.

You are now discussing the compromise between compiler
complexity and ease of language use.

That's a different sort of compromise than that needed in the
design of language in order to balance it for both novice and
expert use. I don't think this will ever go away.

Is this bit of the thread becoming a bit too philosophical?

> In practical terms, it help should cutting down on the need to consult the
> standard. Instead one programs around the more general concepts, which are
> easy to remember, and at the time for optimization or the nitty gritty
> details, one goes in checking just those details.
>
> >> The way it is implemented now, you mean: push_back typically
> >> doubles the memory, leaving the reserved memory at the back.
> >> push_front would have to the same, leaving the memory at the
> >> front.
> >
> >If I understand your proposal correctly it would mean
> >that the obvious implementation of vector would have
> >to change because the first real item of vector's
> >underlying array would no longer be the same as the
> >start of the allocation.
>
> It already is: operator new() typically reserves some memory at the
> beginning, telling the size of the allocation. This part would only be
> larger.

Depends how you define "start of the allocation". I define
it as the byte pointed to by the return value of the allocator's
allocate() function. (Typically the same as operator new()'s
return value.) That's certainly how vector sees it.

> >This is certainly better than the naive push_front I had
> >envisaged, but I can see a number of disadvantage:
>
> All these new, more advanced container classes have
> disadvantages; one realizes on the fact that faster computers
> with ample memory can cope with that. Computer time and
> space becomes increasingly cheaper, whereas human
> programmer time becomes expensive.

This is also a good argument for using deque
when you need push_front.

> >1. It will push the size of the typical implemention up
> >slightly as there is an extra piece of information to track.
> >
> >2. More wasted memory when calls to push_front and
> >push_back are mixed. Off the top of my head I think the
> >average amount of wasted memory would double.
>
> Clearly, those are disadvantages that one would deliberately choose in
> order to ensure a good time complexity, just as in the case of
> push_back().
>
> >I don't think either of these are killers, but I'm afraid I
> >still don't think vector::push_front is worth it.
>
> If you don't use push_front(), there is no change in the
> behavior of vector.

(1) still applies even if you never call push_front().

> Otherwise, I do not know what variation to choose: I only noted
> it seems possible to do it.

Fair enough. All I'm noting is that the cost of
doing so is non-zero.

> >> It seems to be a weakness of current C++ that it is hard to
> >> implement a single interface object which may have
> >> several different implementations.
> >
> >Perhaps a concrete example would be helpful here (something
> >more tangible than the brief calendar description I snipped)
>
> I think that if one only has copy constructors between sequential
> container classes, like
>   vector::vector<T, A1>(const list<T, A2>&);
> where A1, A2 are different allocator classes, that would suffice.

Thanks for clarifying what you meant. I must admit this isn't
what I had in mind when I read your request for a single
interface object with several implementations.

I don't understand why one of the constructors that takes iterator
arguments isn't suitable.

Kind regards

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

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





Author: Helmut Zeisel <atvai398@attglobal.net>
Date: Mon, 14 Jan 2002 17:06:47 GMT
Raw View
In what namespace will the
standard library of ISO C++ 0x be?

Will it still be in namespace std,
or will there be a different namespace
because of possible incompatibilities?

Helmut

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