Wednesday, October 29, 2008

25 new messages in 13 topics - digest

comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en

comp.lang.c++@googlegroups.com

Today's topics:

* what's wrong? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/11b8342c0213e021?hl=en
* STL algorithm to compare if 2 vector<int> have same value? - 2 messages, 2
authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/17a1e81877ace6c1?hl=en
* Class objects work like built-in types, but is it worth it? - 1 messages, 1
author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/2c47abdc653f2dd1?hl=en
* Additional history, was: Re: srand(time(0)) - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/076560d172c254fb?hl=en
* Mimicking Javas static class initializer in C++ - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/e53f4890afb73e63?hl=en
* Is c++ only better c ? - 4 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/38527e42967dc124?hl=en
* Variable Block Text File - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/c53528aeee514123?hl=en
* C/C++ language proposal: Change the 'case expression' from "integral
constant-expression" to "integral expression" - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/a6452a6641b1fc5b?hl=en
* Dealing with a Diamond of Death - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/23939507fa6eb9c8?hl=en
* Question on C++ Thread Class and inheritance/polymorphism with POSIX pthread
- 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d3166146c90fe99b?hl=en
* List erase iterator outside range - 7 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/25a39eff0031f895?hl=en
* Overload Resolution in C++ - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/01ff5ba2e223389e?hl=en
* Sorting a list Structure - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/82cc848a4d1e245a?hl=en

==============================================================================
TOPIC: what's wrong?
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/11b8342c0213e021?hl=en
==============================================================================

== 1 of 1 ==
Date: Tues, Oct 28 2008 11:14 pm
From: questions


On 10月29日, 上午7时18分, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Juha Nieminen wrote:
> > Kai-Uwe Bux wrote:
> >> Juha Nieminen wrote:
>
> >>> questions wrote:
> >>>> y=x%pow(10,3);
> >>> What's wrong with 1000?
>
> >> Nit: 1000 does not occur in the above whereas 1000.0 does occur.
>
> > But 1000 would work, whereas 1000.0 wouldn't.
>
> Ah, now I understand your point: you meant to replace pow(10,3) by 1000.
>
> Sorry for the noise.
>
> Kai-Uwe Bux

thanks


==============================================================================
TOPIC: STL algorithm to compare if 2 vector<int> have same value?
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/17a1e81877ace6c1?hl=en
==============================================================================

== 1 of 2 ==
Date: Wed, Oct 29 2008 12:38 am
From: Salt_Peter


On Oct 28, 5:40 pm, "silverburgh.me...@gmail.com"
<silverburgh.me...@gmail.com> wrote:
> Hi,
>
> Is there a STL algorithm to compare if 2 vector<int> have same values?
>
> Thank you.

That depends what you mean by 'same values'. operator== will do the
job if the two containers are identical (also same size(), capacity()
is ignored). If the containers have the same values but in a different
order then op== returns false.

== 2 of 2 ==
Date: Wed, Oct 29 2008 2:35 am
From: James Kanze


On Oct 28, 11:49 pm, Sam <s...@email-scan.com> wrote:
> silverburgh.me...@gmail.com writes:

> > Is there a STL algorithm to compare if 2 vector<int> have
> > same values?

> a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin())

Which is exactly what a == b would do. And which tests if the
two vector have the same values IN THE SAME ORDER.

The simplest way to see if they have the same values is to sort
them first, then compare. For types other than int, though,
this may mean that you have to define a possibly arbitrary
ordering relationship.

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


==============================================================================
TOPIC: Class objects work like built-in types, but is it worth it?
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/2c47abdc653f2dd1?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Oct 29 2008 1:07 am
From: Paavo Helde


tonytech08 <tonytech08@gmail.com> kirjutas:
>>
> When would you _ever_ want to use containers with value semantics
> other than
> with pointers to objects?

Basically whenever when the objects are not polymorphic. Using pointers
instead of objects themselves adds a level of indirection with its own
complexity and problems, this should be avoided when not needed.

>
> Well the container topic got backed into here. The issue of this
> thread are
> class objects. Using a container (STL) with value sematics for a
> object of
> class type imposes unnecessary requirements on the class.

Nah, you still have it backwards; if the class supports value semantics
one can have value-based containers of the objects (with simplified
semantics), *in addition* to pointer-based containers, which are still
there.

>
> A point is that exceptions and constructors are pretty much a package
> deal because the alternatives are ugly.

It appears you are claiming that if there are two good features fitting
nicely with each other, they should be both banned, for unfair
competition ;-)

Paavo


==============================================================================
TOPIC: Additional history, was: Re: srand(time(0))
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/076560d172c254fb?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Oct 29 2008 1:35 am
From: James Kanze


On Oct 28, 10:59 am, James Kanze <james.ka...@gmail.com> wrote:
> On Oct 26, 2:33 am, bill <bill21...@zippycode.net> wrote:

[...]
> Historically, I think that time() was defined before you could
> return a long.

FWIW, I just checked the documentation of Unix version 7 (the
oldest I could get my hands on). In the specifications for C,
there is no long, period. Which would mean that the "pointer"
would have to be to an array or a struct. On the other hand,
the specification for the function time is "long time(long*)".
So I suspect that my speculations were partially wrong; you
probably could return a long as soon as it was added to the
language, but long itself wasn't added to the language until
fairly late. Late enough not to find its way into the
specifications of C in the documentation, even though it was
used in the system API and the library.

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


==============================================================================
TOPIC: Mimicking Javas static class initializer in C++
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/e53f4890afb73e63?hl=en
==============================================================================

== 1 of 2 ==
Date: Wed, Oct 29 2008 1:40 am
From: James Kanze


On Oct 27, 11:37 pm, Andreas Wollschlaeger <meister.pos...@arcor.de>
wrote:
> Lars Tetzlaff schrieb:
> > Andreas Wollschlaeger schrieb:
> >> as the subject says, i'm a poor Java programmer trying to
> >> transfer some of his wisdom into C++ world... here is what
> >> im trying to do this evening:

[...]
> Well, great, this was just what i have been looking for:
> encapsulating the statics initialization in some inner class
> and its default constructor - much more elegant and
> "cplusplusish" than my previous attempt :-) Tx to you and the
> other folks, added me some more insight to C++ this evening!

Just a bit of additional information. This isn't quite like
Java. C++ is statically linked, and the initialization code will
be executed before entering main (with all existing compilers,
anyway), where as Java uses lazy dynamic loading, and the
initialization code won't be executed until you load the class,
which won't happen until you use something in it. The C++ model
has one definite advantage: the initialization code will be
executed even if you never directly reference the class (e.g.
because it is a derived class, which registers its factory in
the static initializer---a frequent C++ idiom). It also has a
downside: the order of initialization isn't defined, so if one
static initializer depends on another, you may have problems.
(The usual work-around for this is to use the singleton idiom.)

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

== 2 of 2 ==
Date: Wed, Oct 29 2008 2:12 am
From: blargg.h4g@gishpuppy.com (blargg)


In article <49062fa0$0$32668$9b4e6d93@newsspool2.arcor-online.net>,
Andreas Wollschlaeger <meister.possel@arcor.de> wrote:

> Hi folks,
>
> as the subject says, i'm a poor Java programmer trying to transfer some
> of his wisdom into C++ world... here is what im trying to do this evening:
>
> Java has a nifty feature called a static class initializer - something
> like this:
>
> public class Foo
> {
> private static Vector<Thing> xx;
> static
> {
> xx = new Vector<Thing>(42);
> for (int i=0; i < xx.size(); ++i)
> xx.set(i, new Thing());
> }
> }
>
> where the static{} block is called once (when the class is first used),
> thus suitable for complex initializations of static members.
>
> Now i would like to have this in C++, can this be done?

Trying to make as literal a translation here. This will initialize things
the first time a Foo object is created; if no Foo is ever created, this
initialization will never run.

// Foo.hpp
class Foo {
public:
Foo();

private:
static vector<Thing> xx;
}

// Foo.cpp
vector<Thing> Foo::xx;

Foo::Foo()
{
if ( xx.empty() )
{
xx = new Vector<Thing>(42);
for (int i=0; i < xx.size(); ++i)
xx [o] = new Thing();
}
}

Here is a more general approach that separates the init code into its own
function:

// Foo.hpp
class Foo {
public:
Foo();

private:
static void first_use();
}

// Foo.cpp
void Foo::first_use()
{
// initialize statics
}

Foo::Foo()
{
static int call_once = (first_use(),0);
}

You could use a less-hacky approach to having first_use() called only
once, like a helper class, but this is a more concise approach.


==============================================================================
TOPIC: Is c++ only better c ?
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/38527e42967dc124?hl=en
==============================================================================

== 1 of 4 ==
Date: Wed, Oct 29 2008 1:48 am
From: James Kanze


On Oct 27, 7:28 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> blargg wrote:
> > Won't someone think of the compiler writers???

> (As a side note, I detest XML precisely because of that: XML
> has been designed to make it easier to create programs which
> read XML, at the cost of making it harder for users to write
> XML.

It's not quite the same context. While XML is not without its
problems, one of the goals is to allow non-programmers to design
their own language, more or less easily. And because all of
such languages have the same basic grammar, they can all be
based on the same parser, and can all benefit from the same
smart editor tools.

> (Basically XML is pre-tokenized data, which lifts the need for
> the program reading XML to tokenize it.) This is the complete
> reversals of what software should be all about: Software
> should do as much as possible to make the life of the user as
> easy as possible, not the other way around!

In the case of XML, it is the user who defines the language.

> As an example of what I'm talking about, consider MathML vs.
> LaTeX equations, and which one is easier for a human to
> write.)

Neither are, IMHO, particularly simple. MathML will benefit
from an XML aware editor; LaTeX will need special support. In
the case of LaTeX, of course, the language has been around
awhile, and is pretty universal in mathematic circles, so
editors already have that support. The simplest way to use
MathML is probablly to write LaTeX, and pass it through a
converter. But XML is used for many other things, where there
really aren't good existing tools.

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

== 2 of 4 ==
Date: Wed, Oct 29 2008 1:59 am
From: James Kanze


On Oct 28, 6:48 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Gerhard Fiedler wrote:
> > XML is primarily meant for the (easily
> > portable) exchange of data between programs

> And XML is one of the least efficient ways of doing that,
> spacewise. This is especially true with large amounts of data
> which have to be transferred eg. over a network. XML is
> hyperverbose, often for no good reason.

But it compresses well:-). I agree, and this over-verbosity is
one of the things I don't particularly care for in XML. Before
XML, each time I've needed some specialized syntax, i designed
it from scratch (usually with a vaguely lisp-like grammar,
although I'd usually put the keyword outside the parentheses,
and often used {..} for parentheses, rather than (...)). And
write a parser for it, which was good for a couple of days work.
And not have any support (e.g. auto-indent) for it in the
editor. Today, I'll do it in XML, write my DTD in a couple of
hours, and have a complete parser and editor support
immediately.

I'm not really fond of XML, however: it's not that it's better
than any possible alternatives, it's that there are no
alternatives, other than developing an entire data description
language from scratch each time around. The results are never
as good as a custom data description language would be, but a
half a day's work, compared to a week or more (generally more,
because if you define your own format, you have to document it
in detail as well). There are doubtlessly some cases where the
extra work is justified, but file size is rarely a valid
justification, given the omnipresence of gzip, bzip2, etc.

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

== 3 of 4 ==
Date: Wed, Oct 29 2008 3:45 am
From: Gerhard Fiedler


On 2008-10-28 15:48:35, Juha Nieminen wrote:

>> XML is primarily meant for the (easily portable) exchange of data
>> between programs
>
> And XML is one of the least efficient ways of doing that, spacewise.
> This is especially true with large amounts of data which have to be
> transferred eg. over a network. XML is hyperverbose, often for no good
> reason.

XML is as verbose as you make it. If your XML files are too verbose, you
can't really blame the XML definition for that. It's possible to create an
XML spec for a configuration file that is not more verbose than the
standard .ini file format, for example.

<ini cfg1="value1" cfg2="value2"/>

Of course, you can also make this

<MyReallyLongRootNodeName>
<AnEvenLongerConfigurationValueName>
value1
</AnEvenLongerConfigurationValueName>
<AndAnotherStillLongerConfigurationValueName>
value2
</AndAnotherStillLongerConfigurationValueName>
</MyReallyLongRootNodeName>

Neither is required or prohibited by XML. Both are XML (well, there's the
spec line that's missing).

Gerhard

== 4 of 4 ==
Date: Wed, Oct 29 2008 7:01 am
From: ytrembla@nyx.nyx.net (Yannick Tremblay)


In article <h7adnciHX6v11prUnZ2dnUVZ_rDinZ2d@giganews.com>,
Jeff Schwab <jeff@schwabcenter.com> wrote:
>Yannick Tremblay wrote:
>> In article <jtGdnb4HDdYm7pnUnZ2dnUVZ_hWdnZ2d@giganews.com>,
>> Jeff Schwab <jeff@schwabcenter.com> wrote:
>>>
>>> I prefer C for some of the lower level portions of OS kernel and device
>>> driver development, e.g. the code that runs on an ACPI embedded
>>> controller. It's not that the C code is any better than C++ would be,
>>> but that someone reading the code doesn't have to consider every
>>> operation a potential function call. The meaning of an expression like
>>> a+b has a variety of potential meanings, even in C, but the variety is
>>> at least bounded. C is also much nicer than typical C++ to interface
>>
>> Well, if you are going to talk about bad C++ that redefine operator+()
>> for basic types,
>
>You can't redefine operator+ for primitive types, even in C++, thank
>WG21. You can overload operator+ for the case when at least one
>argument is not primitive, but that's not the same thing.

Sorry, my mistake. What I meant was "unnatural" usage of operators.
I.e. defining an operator+() that does something that is not expected.

Example bad code: MFC CRect monstruosity
-----------------------------------------
CRect operator +( POINT point) const throw( );
CRect operator +(LPCRECT lpRect) const throw( );
CRect operator +( SIZE size ) const throw( );
---------------------------------------------

What on earth is adding a point to a rectangle supposed to mean? Or
adding a size to a rectangle? Or even worse, adding a rectangle to
another?

If what they wanted was shifting a recantangle sideway in direction x
and y, why didn't they say so:

CRect shift(xShift, yShift);
or
CRect move(xDirection, yDirection);

Clear and it does what it says but some idiot seem to find the need to
abuse operators for that.

>In well-written C++ code, the reader doesn't have to know exactly what's
>happening at the next lower level of abstraction; for example,

My point.
Anti C++ C hackers claim that because it is possible to write
obfuscated C++, then C++ is bad. Regardless that the same powers that
allow one bad programmer to write obfuscated C++ do allo a good
programmer to write clear code that make appropriate use of levels of
abstraction.

>some_library::smart_pointer's destructor may clean up a resource, or
>flush a buffer; operator-> may return a temporary proxy object whose
>constructor and destructor obtain and release a lock. These techniques
>can be great for high-level programming, but they're wide open to the
>kind of savage abuse that "seems like a good idea at the time." Almost
>any use of them would be dangerous in code that is innately
>hardware-specific. The "next lower level of abstraction" specifically
>should not be hidden from (e.g.) a device driver that needs to
>communicate with the registers on a device controller.
>
>The introduction to The C Programming Language claims that "a programmer
>can reasonably expect to know and understand and indeed regularly use
>the entire language." The same is not true of C++. Note that C++ is my

That's true, it is much more difficult to undertand the whole of the
C++ language.

However, in practice, is it more difficult to understand a
complete application written in C++ than it is to understand an
equivalent application written in C?

I suggest it is in fact easier if good programming practices were
followed. The C++ application should have less lines of code, have
cleaner interfaces without hidden side effect, simpler memory
management, cleaner layering of levels of abstraction, may take
advantages of OO techniques, better generic codes, etc. All stuff
that is more difficult to do in pure C.

So although in C, you can read the low level driver code and be fairly
confident that you fully understand what is happening, it is much more
difficult to shift up in application land and be able to view
everything. C++ allows this process to happen more easily. However,
it is maybe more suceptible to poor coding due to the same power. The
sword has two edges.

>"desert island" language, and I love it dearly, so I don't claim that C
>has its advantages without reason. I also wonder why the C committee
>bothers with quasi-automated features like VLAs, since C's long-term
>niche is clearly with developers who need just enough abstraction to let
>the same code run on target platforms with different assembly languages.
>
>> then one should also consider preprocessor abuse in
>> pure C.
>
>The same preprocessor is available in C++, and seems to be abused with
>roughly equal frequency in both languages. Note that what constitutes
>"abuse" in C++ is often valid in C; for example, macro definitions don't
>respect C++ namespaces, but in C, that's not a problem.

Although it is availabe, it is less often used and abused because the language
offers facilities that are often more appropriate.

So while the bad C++ programmer create unreadable code by abusing the
operator overloading and a monolith of a class hierarchy the does not
follow LSP, the bad C programmer absue the Preprocessor to rewirte
code on the fly with no traces in the current file. :-(


Yannick



==============================================================================
TOPIC: Variable Block Text File
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/c53528aeee514123?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Oct 29 2008 2:05 am
From: James Kanze


On Oct 29, 1:28 am, scad <scadr...@gmail.com> wrote:
> On Oct 28, 4:07 pm, Juha Nieminen <nos...@thanks.invalid> wrote:

> > scad wrote:
> > > I have a file that has blocks of data that can vary in
> > > length. The first 2 bytes of the block are a Hex number
> > > telling me how many bytes long the block is (including
> > > those 2 bytes).

> > Are you sure the two bytes form a hexadecimal number (in
> > ascii?), that is, the maximum size of the block is 255 bytes
> > (ie. FF in hex), rather than the two bytes forming a 16-bit
> > value telling the size of the block (ie. the maximum size
> > would then be 65535 bytes)?

> > The solution is obviously different depending on that. Also
> > in the latter case it depends on whether the two bytes form
> > a low-endian or a high-endian value.

> It is a 16-bit value. 7F 88 = 32648

And how is this binary value represented? Without knowing that,
we can't read it. If it's the same as an unsigned short in XDR,
something like:

unsigned short result = input.get() ;
result |= result << 8 | input.get() ;

would do the trick (except for error handling). If the format
is something else, you'd need something different.

And of course, this only works if you open the file in binary.
Similarly, reading the data, then outputing it with a trailing
'\n', will likely only work if the data is text, encoded in the
same character set as you normally use.

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


==============================================================================
TOPIC: C/C++ language proposal: Change the 'case expression' from "integral
constant-expression" to "integral expression"
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/a6452a6641b1fc5b?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Oct 29 2008 2:17 am
From: James Kanze


On Oct 28, 7:24 pm, Matthias Buelow <m...@incubus.de> wrote:
> Adem wrote:
> > C/C++ language proposal:
> > Change the 'case expression' from "integral
> > constant-expression" to "integral expression"

> How about:

> cond {
> (foo == bar): ...; break;
> (!bar && (baz == boo)): ...; /* fallthru */
> default: ...; break;
> }

> In pseudo-grammar:

> cond { [<expr>|default: <stmt>*]* }

I once designed a language with something like that, many, many
years back. In fact, the grammar was a bit more complete,
something like:

cond_stmt := 'cond' [<expr1>] '{' case_list '}'
case_list := /* empty */ | case_list case_clause
case_clause := 'case' [<op>] expr2 ':' stmt
| 'default' ':' stmt

If expr1 was absent, <op> was forbidden, and it worked exactly
like your suggestion (except that there was no fall through---a
case controlled exactly one statement). If expr1 was present,
it was the equivalent of having written "case <expr1> <op>
<expr2>" for each case, except that expr1 was only evaluated
once; if you omitted the <op> in this case, it defaulted to ==,
so you could write things like:

cond x {
case > 0 : ... ;
case == 0 : ... ;
case < 0 : ... ;
}

or

cond c {
case 'a' : ... ;
case 'b' : ... ;
case 'c' : ... ;
}

(IIRC, the keyword was actually select, and not cond, and I used
OF .. END instead of {..}. But the basic idea was the same.)

The idea was basically that there are only four basic structured
constructs: a loop, a choice, a sequence, and a procedure call,
and thus, there were only four basic execution statements.

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


==============================================================================
TOPIC: Dealing with a Diamond of Death
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/23939507fa6eb9c8?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Oct 29 2008 2:27 am
From: James Kanze


On Oct 28, 11:52 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Jeff Schwab wrote:
> >> Why the heck do they have to forbid multiple inheritance in
> >> order to avoid diamond inheritance? Why not forbid diamond
> >> inheritance only? There are tons of situations where
> >> non-diamond multiple inheritance would be extremely useful,
> >> but these languages go ahead and remove this useful
> >> object-oriented tool.

> > I suspect that they avoid MI because of difficulty
> > implementing it, rather than difficulty using it.

> Is it really so difficult to implement multiple inheritance in
> a language and its compilers?

> I do understand that diamond inheritance (what C++ implements
> as virtual inheritance) can become complicated. However, what
> makes multiple inheritance complicated?

Well, multiple inheritance without virtual base classes is
pretty useless. Practically speaking, if you support multiple
inheritance, virtual inheritance should almost be the default.

I think multiple inheritance may have gotten a bad name because
virtual inheritance wasn't the default. The diamond pattern
works perfectly well; having multiple instances of the same base
class can cause serious problems. The only real problem with
the diamond pattern in C++ is knowing where to put the virtual
keywords---if inheritance were virtual by default, that problem
would disappear. (There was also a bug in early CFront
implementations which meant that virtual inheritance resulted in
outrageously large classes. Which gave virtual inheritance a
bad name in memory tight situations.)

Another reason some people opposed (and perhaps still oppose)
multiple inheritance is because Smalltalk didn't have it. But
Smalltalk didn't have inheritance of interface, in the sense we
think of it in C++: it didn't require an interface to be
declared, and you could call any possible function on any object
(and get a runtime error if the object didn't support that
function). With static type checking, multiple inheritance
(using the equivalent of virtual inheritance) is practically a
necessity, and all of the OO languages I know with static type
checking support it. (Of course, that's not very many: C++ and
Java.)

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


==============================================================================
TOPIC: Question on C++ Thread Class and inheritance/polymorphism with POSIX
pthread
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d3166146c90fe99b?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Oct 29 2008 3:06 am
From: Szabolcs Ferenczi


On Oct 29, 12:07 am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> FWIW, here is a quick example (in the form of a fully compliable program
> with error checking omitted) of how I use POSIX threads within a C++
> environment:
> _________________________________________________________________
> /* Simple Thread Object
> ______________________________________________________________*/
> #include <pthread.h>
>
> extern "C" void* thread_entry(void*);
>
> class thread_base {
>   pthread_t m_tid;
>   friend void* thread_entry(void*);
>   virtual void on_thread_entry() = 0;
>
> public:
>   virtual ~thread_base() = 0;
>
>   void thread_run() {
>     pthread_create(&m_tid, NULL, thread_entry, this);
>   }
>
>   void thread_join() {
>     pthread_join(m_tid, NULL);
>   }
>
> };
>
> thread_base::~thread_base() {}
>
> void* thread_entry(void* state) {
>   reinterpret_cast<thread_base*>(state)->on_thread_entry();
>   return 0;
>
> }
>
> template<typename T>
> struct thread : public T {
>   thread() : T() {
>     this->thread_run();
>   }
>
>   ~thread() {
>     this->thread_join();
>   }
>
>   template<typename T_p1>
>   thread(T_p1 p1) : T(p1) {
>     this->thread_run();
>   }
>
>   template<typename T_p1, typename T_p2>
>   thread(T_p1 p1, T_p2 p2) : T(p1, p2) {
>     this->thread_run();
>   }
>
>   // [and on and on for for params...]
>
> };
>
> /* Simple Usage Example
> ______________________________________________________________*/
> #include <string>
> #include <cstdio>
>
> class worker : public thread_base {
>   std::string const m_name;
>
>   void on_thread_entry() {
>     std::printf("(%p)->worker(%s)::on_thread_entry()\n",
>       (void*)this, m_name.c_str());
>   }
>
> public:
>   worker(std::string const& name)
>     : m_name(name) {
>     std::printf("(%p)->worker(%s)::my_thread()\n",
>       (void*)this, m_name.c_str());
>   }
>
>   ~worker() {
>     std::printf("(%p)->worker(%s)::~my_thread()\n",
>      (void*)this, m_name.c_str());
>   }
>
> };
>
> int main(void) {
>   {
>     thread<worker> workers[] = {
>       "Chris",
>       "John",
>       "Jane",
>       "Steve",
>       "Richard",
>       "Lisa"
>     };
>
>     worker another_worker("Jeff");
>     another_worker.thread_run();
>     another_worker.thread_join();
>   }
>
>   std::puts("\n\n\n__________________\nhit <ENTER> to exit...");
>   std::fflush(stdout);
>   std::getchar();
>   return 0;}
>
> _________________________________________________________________
>
> IMVHO, this is very straight forward and works well. In fact, I think I like
> it better than the Boost method... Humm... Well, what do you all think about
> the design? Is it crap?

The active object concept is much better than the Boost thread and I
have suggested it earlier that the C++0x committee should consider
this pattern, i.e. active object, as a high level wrapper construction
next to their high level wrapper wait/2 on the condition variable:

<quote from="
http://groups.google.com/group/comp.lang.c++/msg/8e80468d988c4feb
">
I do think it has advantages over Boost's method. One such advantage
is the RAII nature of it.

Furthermore, I think it should be taken in into the C++0x standard on
the similar grounds as they provide higher level condition variable
wait API as well:

<quote>
template <class Predicate>
void wait(unique_lock<mutex>& lock, Predicate pred);
Effects:
As if:
while (!pred())
wait(lock);
</quote>
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html
</quote>

Another remark: Why do you not keep to the terminology we have come up
with earlier? It is for an active object and not for any plain thread.
See:

"What's the connection between objects and threads?"
http://groups.google.com/group/comp.lang.c++/msg/84d6d69cae17fee7

What is the difference between:

worker another_worker("XY");
another_worker.thread_run();
another_worker.thread_join();

and

ActiveObject<worker> another_worker("XY");

Well, the difference is that the wrapper takes care of the low level
details of starting and stopping the thread. As a bonus, it is
impossible to miss to join the thread. In other frameworks they tend
to call it the fork-join style.

So, you might consider this patch for clarity:

34,35c34,35
< struct ActiveObject : public T {
< ActiveObject() : T() {
---
> struct thread : public T {
> thread() : T() {
39c39
< ~ActiveObject() {
---
> ~thread() {
44c44
< ActiveObject(T_p1 p1) : T(p1) {
---
> thread(T_p1 p1) : T(p1) {
49c49
< ActiveObject(T_p1 p1, T_p2 p2) : T(p1, p2) {
---
> thread(T_p1 p1, T_p2 p2) : T(p1, p2) {
86c86
< ActiveObject<worker> workers[] = {
---
> thread<worker> workers[] = {

I believe that the program will be clearer and more readable if you
keep to the terminology that reflects the active object. It is not a
good idea to overload the term `thread' since it will just cause some
more confusion.

Best Regards,
Szabolcs


==============================================================================
TOPIC: List erase iterator outside range
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/25a39eff0031f895?hl=en
==============================================================================

== 1 of 7 ==
Date: Wed, Oct 29 2008 3:20 am
From: Krice


I get "list erase iterator outside range" message from MSVC with this
function:

int Level::Remove_Npc(Game_Object *o)
{
list <Game_Object *>::iterator pos;
Game_Object *c;

for (pos=npc_list.begin(); pos!=npc_list.end(); pos++)
{
c=(*pos);
if (c==o)
{
c->Clear_From_Map();
delete c;
item_list.erase(pos);
return 0;
}
}
return -1;
}

I have also Level::Remove_Item which operates item_list, but it seems
to be working.
It's exactly like this one. Is something wrong here?

== 2 of 7 ==
Date: Wed, Oct 29 2008 3:25 am
From: Krice


On 29 loka, 12:20, Krice <pau...@mbnet.fi> wrote:
> item_list.erase(pos);

Eh, oops.. cut-pasted the code, but forgot to rename this one
to npc_list. Bug fixed.

== 3 of 7 ==
Date: Wed, Oct 29 2008 6:31 am
From: Marcel Müller


Krice schrieb:
> I get "list erase iterator outside range" message from MSVC with this
> function:
>
> int Level::Remove_Npc(Game_Object *o)
^^^ ^^^
Approximately here I get the first bunch of compiler errors.

So please either post resonable C++ code or choose an appropriate newsgroup.


Marcel

== 4 of 7 ==
Date: Wed, Oct 29 2008 6:46 am
From: Maxim Yegorushkin


On Oct 29, 1:31 pm, Marcel Müller <news.5.ma...@spamgourmet.com>
wrote:
> Krice schrieb:> I get "list erase iterator outside range" message from MSVC with this
> > function:
>
> > int Level::Remove_Npc(Game_Object *o)
>
>        ^^^               ^^^
> Approximately here I get the first bunch of compiler errors.
>
> So please either post resonable C++ code or choose an appropriate newsgroup.

This particular question does not take a rocket scientist to infer
that:
* Level is a class or a namespace name.
* Game_Object is a class with a member function Clear_From_Map().
* npc_list is a std::list<Game_Object*> object, accessible from Level.

To make it compile you add some code like that:

#include <list>

struct Game_Object
{
void Clear_From_Map();
};

struct Level
{
int Remove_Npc(Game_Object *o);
std::list<Game_Object *> npc_list;
};

using std::list;

// original piece of code follows

--
Max

== 5 of 7 ==
Date: Wed, Oct 29 2008 6:50 am
From: Lionel B


On Wed, 29 Oct 2008 03:20:41 -0700, Krice wrote:

> I get "list erase iterator outside range" message from MSVC with this
> function:
>
> int Level::Remove_Npc(Game_Object *o) {
> list <Game_Object *>::iterator pos;
> Game_Object *c;
>
> for (pos=npc_list.begin(); pos!=npc_list.end(); pos++) {
> c=(*pos);
> if (c==o)
^^^^^^^^^

if (c != 0)

> {
> c->Clear_From_Map();
> delete c;
> item_list.erase(pos);
> return 0;
> }
> }
> return -1;
> }
>
> I have also Level::Remove_Item which operates item_list, but it seems to
> be working.
> It's exactly like this one.

I doubt it...

> Is something wrong here?

--
Lionel B

== 6 of 7 ==
Date: Wed, Oct 29 2008 7:02 am
From: Krice


On 29 loka, 15:31, Marcel Müller <news.5.ma...@spamgourmet.com> wrote:
> Approximately here I get the first bunch of compiler errors.

Wow, what a surprise!

> So please either post resonable C++ code

Fuck you.

== 7 of 7 ==
Date: Wed, Oct 29 2008 7:05 am
From: Krice


On 29 loka, 15:50, Lionel B <m...@privacy.net> wrote:
> > if (c==o)
>
> ^^^^^^^^^
>
> if (c != 0)

You fail.


==============================================================================
TOPIC: Overload Resolution in C++
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/01ff5ba2e223389e?hl=en
==============================================================================

== 1 of 2 ==
Date: Wed, Oct 29 2008 4:45 am
From: zbigniew@szymczyk.eu


Can someone explain me how overload resolution works in C++?

For example if I have function void f(char, int); and I will call
f('A', 3.1) or f(1.5, 3.1F) what would be the result?

Thanks

== 2 of 2 ==
Date: Wed, Oct 29 2008 6:06 am
From: Victor Bazarov


zbigniew@szymczyk.eu wrote:
> Can someone explain me how overload resolution works in C++?
>
> For example if I have function void f(char, int); and I will call
> f('A', 3.1) or f(1.5, 3.1F) what would be the result?

If you only have a single function called 'f', no overload is present.
Overload is only there if you have more than one function named 'f':

void f(char, int);
void f(long, double);

int main() {
f(0L, 0.0); // the latter is called
f('c', 42); // the former is called
}

Explaining how overload resolution "works" can take weeks. Please find
a decent C++ book and read the section/chapter on overloading.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


==============================================================================
TOPIC: Sorting a list Structure
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/82cc848a4d1e245a?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Oct 29 2008 5:38 am
From: mrc2323@cox.net (Mike Copeland)


> > I have populated the list successfully, and now I want to sort the
> > list on the netTime element. All examples of the list.sort I've found
> > work only with scalars or single-element structures. How do I do this
> > with my data? TIA
>
> You either define an operator<() in your Finishes struct, or you give
> a comparator function to the std::list::sort() function as a parameter.
>
> If comparing objects of type 'Finishes' with the < operator is
> rational, that's the easiest solution. In other words, you would do this:
>
> struct Finishes
> {
> long netTime;
> int bibNumber;
>
> bool operator<(const Finishes& rhs) const
> {
> return netTime < rhs.netTime;
> }
> };

Yes, that works perfectly. Thanks!

==============================================================================

You received this message because you are subscribed to the Google Groups "comp.lang.c++"
group.

To post to this group, visit http://groups.google.com/group/comp.lang.c++?hl=en

To unsubscribe from this group, send email to comp.lang.c+++unsubscribe@googlegroups.com

To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.c++/subscribe?hl=en

To report abuse, send email explaining the problem to abuse@googlegroups.com

==============================================================================
Google Groups: http://groups.google.com/?hl=en

No comments: