Topic: overloading operator ,


Author: kanze@gabi-soft.de
Date: Sun, 10 Sep 2000 06:56:44 GMT
Raw View
boris_fomitchev@my-deja.com writes:

|>  In article <86em3la8pk.fsf@gabi-soft.de>,
|>    kanze@gabi-soft.de wrote:
|>  > Coming from a C background, however, in modern C++, I would probabl=
y
|>  > want something like:

|>  >     cout( formatString ).with( arg1 ).with( arg2 ) ;

|>  > The problem is, this requires template member functions and a
|>  > precise rule about the lifetime of temporaries to work correctly.
|>  > Neither were available when the first iostream saw the day.  (Note
|>  > that this can be made neatly thread-safe without a user defined
|>  > mutex as well.  The operator()(string) on ostream returns a
|>  > temporary object which collects and formats the data; its
|>  > destructor triggers the actual output.)

|>  There is more serious problem with your example : it's impossible to
|>  define with() for user-defined type outside the stream class, that's
|>  why shift operator works better ;)

Nonsense.  The user just has to specialize the template function to do
what he wants.  I've tried this with g++.  It works.  I'll have to
verify, however, that my test cases do use a specialization of with for
a user defined type.  However, I *do* specialize with for all of the
built-in types -- couldn't handle format specifications like "%*.*f"
otherwise.

|>  Of course, you may define with() template method to call operator <<,
|>  but that would be syntactic sugar only.

That's exactly what the default implementation does.  Defining an
operator<< is the *standard* method of defining the output formatting
for a user defined class.  Given this, it would be a major design error
not to use it when nothing else was available.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: boris_fomitchev@my-deja.com
Date: Thu, 7 Sep 2000 08:25:05 GMT
Raw View
In article <86em3la8pk.fsf@gabi-soft.de>,
  kanze@gabi-soft.de wrote:
> Coming from a C background, however, in modern C++, I would probably
> want something like:
>
>     cout( formatString ).with( arg1 ).with( arg2 ) ;
>
> The problem is, this requires template member functions and a precise
> rule about the lifetime of temporaries to work correctly.  Neither
were
> available when the first iostream saw the day.  (Note that this can be
> made neatly thread-safe without a user defined mutex as well.  The
> operator()(string) on ostream returns a temporary object which
collects
> and formats the data; its destructor triggers the actual output.)


There is more serious problem with your example : it's impossible to
define with() for user-defined type outside the stream class, that's why
shift operator works better ;)
Of course, you may define with() template method to call operator <<,
but that would be syntactic sugar only.
BTW, i also like formatting manipulators.

-Boris.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 2000/08/25
Raw View
David R Tribble wrote:
...
> C99 has added the ability to pass an array and have the called
> function receive the size of the array.  (I don't know the details,
> however; see 6.7.5.3 of C99.)  Maybe C++ will add this feature some
> day.
>
> You can get the size of array objects using templates, e.g.:
>
>     template <int N>
>     void foo(int a[N])
>     {
>         ... a has N elements ...
>     }
>
> The drawback is that this function gets instantiated for every
> possible array size passed to foo<>().

Section 14.8.2.1p2 says that "If A is an array type, the pointer type
produced by the array-to-pointer standard conversion is used in place of
A for type deduction." 14.8.2.4p13 contains a Note which clarifies this:
"except for reference and pointer types, a major array bound is not part
of a function parameter type and cannot be deduced form an argument".
However, that note also shows how to get around that problem. Just
change the declaration of 'a' to 'int (&a)[N]'.

You can minimize the wasted instantiations by defining:

gen_foo(int a[], int n){
 // Actual code, only one definition.
}

template <int N>
inline void foo(int (&a)[N])
{
 gen_foo(a,N);
}

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "David Thompson" <david.thompson1@worldnet.att.net>
Date: 2000/08/26
Raw View
Trevor L. Jackson, III <fullmoon@aspi.net> wrote :
....
> <rant>
> The issue of array init interests me because I'd like to see partial array
> initialization deprecated.  IMHO under initialization (fewer initializers than
> elements) is an error just as over initialization is an error.  The only
> sensible mechanism I've found is to leave array sizes undefined (which is an
> efficiency hit) so that code using the array can assert that the actual size
> taken from the init list matches the desired size.
>
How is this an efficiency hit?  An array type (object) whose bound
is determined by the initialization-list is still an array-of-(fixed)N
and should generate exactly the same code as one declared
explicitly with the same bound.  Unless you mean doing the assert
(in the obvious way) is the efficiency hit -- in which case, make it
a "compile-time assert":

float foo[] = { 1.0, 2.0, 3.0 ... };

char check_foo [ sizeof foo/sizeof foo[0] == 3 ? 1 : -1 ];

> But this fails for multi-dimensioned arrays.
>
True.  (Unless you only want it for the leftmost dimension.)

> If I could be sure that the compiler would complain about under init I'd be
> free to declare the desired array sizes without becoming vulnerable to init
> list maintenance leaving some elements uninitialized.
> </rant>
>
Ask the implementor for a *warning*, perhaps as an option.
gcc already has a warning for the somewhat similar case
of not-fully-braced structure (and multidim) initializers.
Designated initializers may make this hard in C99,
and in C++ if taken up; you might want to settle for
"warn if init list does not *end at* declared bound".

> Redefining the comma operator is extremely useful in avoiding this situation
> because one can achieve initialization replication (filling multiple elements
> from a single initializer) by overloading the comma operator.  The version
> taking a simple type only fills one element.  The version taking a
> pair<init,count> fills (count) elements.  When count is negative it fills "the
> rest", or in strange cases all but the last abs(count) elements.
>
This (sometimes) makes it less work to get it right,
but I don't see that it prevents you from getting it wrong.

--
- David.Thompson 1 now at worldnet.att.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jerry Coffin <jcoffin@taeus.com>
Date: 2000/08/30
Raw View
In article <39A079DC.1AA4CE4B@aspi.net>, fullmoon@aspi.net says...

[ ... ]

> The point is that it is impossible to tell whether an array has been fully
> explicitly initialized as opposed to partially explicitly initialized.  Would
> you care to address the point at issue?

I will: I think the array part of this argument is mostly a red
herring.  If a particular type should always be explicitly
initialized when it's in an array, it should probably be explicitly
initialized when it's not in an array either.  In this case, you
write a class with no default ctor, and voila' all objects of the
class must always be explicitly initialized.

OTOH, if you really DO need all the elements in an array to be
initialized, it looks to like it might not be particular beautiful,
but some clever use of templates should do the job.  If you create a
pointer to an array, the size of the array pointed to is part of the
type, and a pointer to a different size of array won't match.

The language seems to already provide the tools to deal with the
problem you're citing.  As I recall, Dr. Stroustrup has acted less
than enthused about people talking about the "spirit of C++", but I
think I'll go out on a limb anyway, and say that I think this fits
the spirit of C++ quite well.

For a long time, people tried to build languages with "perfect"
built-in features (e.g. APL).  I'd characterize the "spirit" of C++
as taking the opposite approach: it admits that regardless of what
decisions are made about the built-in features, they'll usually be
wrong (at least to some degree).  Rather than attempting to perfect
them, it makes them less relevant and instead provides the
flexibility for the programmer to write classes with the features
important to the problem and/or programmer at hand.

The semantics of the arrays built into the language should hardly
ever matter to most people, because using a built-in array should be
a relatively rare occurrence except in the implementation of a class
that provides array semantics more suited to the job at hand.

--
    Later,
    Jerry.

The Universe is a figment of its own imagination.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <FrancisG@robinton.demon.co.uk>
Date: 2000/08/21
Raw View
In message <39A079DC.1AA4CE4B@aspi.net>, Trevor L. Jackson, III
<fullmoon@aspi.net> writes
>> In article <399E0C97.BC5E564B@aspi.net>, Trevor L. Jackson, III
>> <fullmoon@aspi.net> writes
>> >If I could be sure that the compiler would complain about under init I'd be
>> >free to declare the desired array sizes without becoming vulnerable to init
>> >list maintenance leaving some elements uninitialized.
                                           ^^^^^^^^^^^^^

That is what you wrote, and that can only be the case if no
initialisation takes place.

>>
>> But they aren't, if an array has insufficient initialisers though at
>> least one has been provided the extras are zero initialised. I would
>> hate it if it were otherwise. To my mind the current rule is exactly
>> right.
>
>The presence of a partial initializer is irrelevant.

Not in what I was commenting on.
>
>Zero initialization is not appropriate for all elements.  Consider pointers.
So? Pointers can be zero initialised (they become null pointers)

>
>The point is that it is impossible to tell whether an array has been fully
>explicitly initialized as opposed to partially explicitly initialized.  Would
>you care to address the point at issue?

It is only impossible to determine if you explicitly zero initialise the
last element you provide an initialiser for, or you are using types fore
which zero initialisation cannot be tested for, which are a pretty
specialist subset of all types.


>

--
Francis Glassborow

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david@tribble.com>
Date: 2000/08/21
Raw View
David R Tribble <david@tribble.com> writes:
>> The Blitz++ library is an example of the numerical folk who can
>> use operator overloading to their advantage.  But outside the domain
>> of numerical applications, I personally find operator overloading
>> to be more confusing than using regular functions.
>>
>>    cout << x;       // Shift x to the output?
>>    cout.print(x);   // Is this really less readable?

"llewelly."@@edevnull.dot.com wrote:
> The principal problem with having an [io]stream::print() method is
>   that C++ has no type safe variable argument functions; such a print
>   method would have to take a fixed number of arguments, making stream
>   i/o quite tedious and irritating.
>
> Overloading a operator<<() is used as a kind of substitute. I do not
>   think that << and >> are 'obvious' i/o operators, but I do think
>   that their use in C++ streams is just about the best overall
>   decision the language allows.

My fault for not providing a prototype for cout.print(), which I
intended to be a fixed-argument function.  All of the printf/scanf
functions could be replaced with fixed-argument member functions
(with default arguments for convenience).

    class ostream   // or whatever
    {
        int  print(int x,    int width=0, int prec=0, char fill=' ');
        int  print(long x,   int width=0, int prec=0, char fill=' ');
        int  print(double x, int width=0, int prec=0, char fill=' ');
        int  print(const char *x,
                             int width=0, int prec=0, char fill=' ');
        //etc.
        ...
    };

How is making multiple calls to cout.print() less convenient that
making multiple calls to cout.operator<<() ?  Slightly more verbiage,
yes, but my original point was that overloaded operators are more
confusing that regular function calls.  I doubt anyone would really
have trouble figuring our what cout.print(x) does.  And once you
throw in things like formatting widths, radixes, precisions, fill
characters, and so forth, single function calls dosn't look so bad
compared to multiple '<<' operators.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: llewelly.@@edevnull.dot.com
Date: 2000/08/21
Raw View
Francis Glassborow <FrancisG@robinton.demon.co.uk> writes:

> In message <39A079DC.1AA4CE4B@aspi.net>, Trevor L. Jackson, III
> <fullmoon@aspi.net> writes
> >> In article <399E0C97.BC5E564B@aspi.net>, Trevor L. Jackson, III
> >> <fullmoon@aspi.net> writes
> >> >If I could be sure that the compiler would complain about under
> >> >init I'd be free to declare the desired array sizes without
> >> >becoming vulnerable to init
> >> >list maintenance leaving some elements uninitialized.
>                                            ^^^^^^^^^^^^^
>
> That is what you wrote, and that can only be the case if no
> initialisation takes place.
>
> >>
> >> But they aren't, if an array has insufficient initialisers though at
> >> least one has been provided the extras are zero initialised. I would
> >> hate it if it were otherwise. To my mind the current rule is exactly
> >> right.
> >
> >The presence of a partial initializer is irrelevant.
>
> Not in what I was commenting on.
> >
> >Zero initialization is not appropriate for all elements.  Consider pointers.
> So? Pointers can be zero initialised (they become null pointers)

8.5.1/7:

# If there are fewer initializers in the list than there are members
# in the aggergate, then each member not explicitly initialized shall
# be default-initialized (8.5).

Default-initialized amounts to zero-initialized in the case of
  pointers, but that is not always the case. I think this lends
  strength to Francis Glassborow's argument that the present behavior
  is seldom a significant problem, and is often an advantage.

>
> >
> >The point is that it is impossible to tell whether an array has been fully
> >explicitly initialized as opposed to partially explicitly
> >initialized.  Would you care to address the point at issue?
>
> It is only impossible to determine if you explicitly zero initialise the
> last element you provide an initialiser for, or you are using types fore
> which zero initialisation cannot be tested for, which are a pretty
> specialist subset of all types.

[snip]

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/08/21
Raw View
Michiel Salters wrote:
>
> [ Snipped quite a lot. MS. ]
>
> "llewelly."@@edevnull.dot.com wrote:
>
> > David R Tribble <david@tribble.com> writes:
>
> > >    cout << x;       // Shift x to the output?
> > >    cout.print(x);   // Is this really less readable?
>
> > The principal problem with having an [io]stream::print() method is
> >   that C++ has no type safe variable argument functions; such a print
> >   method would have to take a fixed number of arguments, making stream
> >   i/o quite tedious and irritating.
>
> > Overloading a operator<<() is used as a kind of substitute. I do not
> >   think that << and >> are 'obvious' i/o operators, but I do think
> >   that their use in C++ streams is just about the best overall
> >   decision the language allows.
>
> The problem of no variable argument lists is as much a problem for
> ostream::print() as it is for ostream::operator<<(), that is, no
> problem at all. But I'd call it ostream::pr() to shorten it:
>
> cout.pr("The price is ").pr(5).pr(" dollar and ").pr(52).pr("Cents");

What about overloading just operator():

cout ("The price is ") (5) (" dollar and ") (52) (" Cents.");

Seens quite readable to me. Indeed, I think an implementation
could allow this as extension (I don't think this syntax is
currently allowed). To provide maximum compatibility,
ostream::operator() would be implemented as

template<class T>
 ostream& ostream::operator()(T const& t)
{
  return *this << t;
}

(actually, this would be in basic_ostream<...>, of course)

[...]

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 2000/08/21
Raw View
"Trevor L. Jackson, III" <fullmoon@aspi.net> wrote...
> Victor Bazarov wrote:
>
> > "Trevor L. Jackson, III" <fullmoon@aspi.net> wrote...
> > > It's an idiom.  You don't expect to read idioms literally.
> >
> > No, but you would expect to understand the '+' as "addition" for any
> > type defining it, wouldn't you?  Or unary '-' as negation of some
> > kind...
> >
> > There are predefined meanings to language constructs, and those are
> > dictated partially by operator precedence.  Would you expect to read
> > a < b as assigning some part of the value b to the respective part of a?
> > Or would you expect a << b to mean "much less than" for some type?  I
> > wouldn't.
>
> Funny you should mention this example.  I agree that operators should not
> surprise their users.  But a couple months ago I asked exactly this
question
> regarding using <<, <<=, >> amd >>= as relational operators.  My concern
was
> the strength of the presumption on the part of the average reader.
>
> Now if you came across code like this:
>
>     void func( UDT const & value, UDT const & limit )    // You can assume
a
> UDT is a complex numeric type
>     {
>         if ( X <<= Y ) {
>             /* Munch on X */
>         }
>     }
>
> ... would it really be that confusing?

Well, er, it would.  What *are* X and Y?  Did you mean to say

        if ( value <<= limit ) {
            /* Munch on value */
        }

And even in that case, I don't understand the meaning of <<=.

In mathematics I learned, '<<' meant "much less than".  What
does equal sign do to that expression?

Are we talking of the same thing here?

>
> >  Maybe I am just too thickheaded...  Well, that's why I am
> > explaining this to you now.
> >
> > > [...]
> > >
> > > >
> > > > The expression
> > > >     <variable> = <value>, <value>, <value>
> > > > does NOT mean
> > > >     <variable> := SOMECOMBINATIONOF(<value>,<value>,<value>)
> > > > to me.
> > > >
> > > > The LANGUAGE, while allowing for such strange constructs, should
> > > > NOT be used in such way, IMHO.
> > > >
> > > > I can understand
> > > >     A(1, 0, 1); // some kind of freaky function call (through '...')
> > > > but not what they did.  However KEWL they might consider it.
> > >
> > > Do you have the same difficulty with:
> > >
> > >     cout << 1 << 0 << 1;
> > >
> > > ... It's the same kind of idiom.
> >
> > Not really.  The above is the same as
> >
> >     whatever + 1 + 3 + 123;
> >
> > Left-to-right associativity, no precedence tricks.
> >
> > Imagine that with some kind of overloading this
> >
> >     whatever -> a == b == c ;
> >
> > means "distribute whatever between a, b, and c evenly".  Do you
> > expect that to happen just by reading that "idiom"?  And I am fairly
> > sure it can be done since operator -> has higher precedence than
> > operator ==.
> >
> > Should it be done?  I don't think so.  And if I see something like
> > that, I wouldn't be able to understand it right away.
>
> Agreed.  But the context, which is typically limited to initialization, is
> going to give a reasonable hint to the reader.  I suppose that I prefer
the
> first of these two alternatives for reasons of readability:
>
>     array_t A = 1, 2, 3, 4, 5;
>     array_t A, 1, 2, 3, 4, 5;

Actually, it is impossible to do because the declaration above
does NOT invoke the comma operator.  You are confusing it with
assignment

    array_t A;
    A = 1, 2, 3, 4, 5; // here the comma operator is used.
    array_t A = 1, 2;  // this is syntax error - int constant
                       // in a declarator list.

>
> ... which brings up another alternative: overloading the assignment
operator
> to perform incremental initialization.  Would you find
>
>     array_t A = 1 = 2 = 3 = 4 = 5;
>
> ... to be as confusing?  To me the sequence looks less like a list of
values
> that the comma delimited init above.

I agree that the comma may look better.  What I would like to have
in the language is an ability to declare a constant that means
"array of", like in

    array_t A = { 1,2,3,4 }; // the '{ ... }' should be treated
                             // as an array of ints just like
                             // '"abcd"' is treated as an array
                             // of chars.

considering that the class array_t is defined as

class array_t
{
    ...
public:
    array_t(int a[]) { ... use the array, AND KNOW ITS SIZE TOO ... }
    ...
};

The distinction between _an_array_of_T_ and _a_pointer_to_T_ is
invaluable for those who deal with vectors, tensors, matrices, etc.

It would bring up, of course, such difficult topics like ability to
assign arrays, convert arrays to something else...  I understand
that it probably was the reason the arrays were NOT made a fully
capable element of the language.  I probably need to read more on
the design and evolution...

>
> <rant>
> The issue of array init interests me because I'd like to see partial array
> initialization deprecated.  IMHO under initialization (fewer initializers
than
>
> elements) is an error just as over initialization is an error.  The only
> sensible mechanism I've found is to leave array sizes undefined (which is
an
> efficiency hit) so that code using the array can assert that the actual
size
> taken from the init list matches the desired size.
>
> But this fails for multi-dimensioned arrays.
>
> If I could be sure that the compiler would complain about under init I'd
be
> free to declare the desired array sizes without becoming vulnerable to
init
> list maintenance leaving some elements uninitialized.
> </rant>
>
> Redefining the comma operator is extremely useful in avoiding this
situation
> because one can achieve initialization replication (filling multiple
elements
> from a single initializer) by overloading the comma operator.  The version
> taking a simple type only fills one element.  The version taking a
> pair<init,count> fills (count) elements.  When count is negative it fills
"the
>
> rest", or in strange cases all but the last abs(count) elements.
>
> I'd like to use a similar mechanism for array allocation initialization,
but
> am not satisfied that it can be done cleanly in all cases.

Victor
--
Please remove capital A's from my address when replying by mail



---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Stephen Howe" <SPAMGUARDstephen.howe@dial.pipex.co.uk>
Date: 2000/08/21
Raw View
Victor Bazarov <vAbazarov@dAnai.com> wrote in message
news:8nhd91$42p$1@bob.news.rcn.net...

> No, but you would expect to understand the '+' as "addition" for any
> type defining it, wouldn't you?  Or unary '-' as negation of some
> kind...

No. Addition of strings is quite different from addition of integers. It is
what the C++ community is used to. I am sure it could get used to '+' for
some other binary operation if it had to just as I had to get used to

cout << "12";

as some type of output operator and not think "left shift".

Stephen Howe



---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Scott Robert Ladd" <sladd@tampabay.rr.com>
Date: 2000/08/21
Raw View
"David R Tribble" <david@tribble.com> wrote in ...

> My opinion is to avoid operator overloading whenever possible,
> especially the more confusing operators like: , ^ << >>.

Which is exactly why I've always felt that C++ mistakenly overloads << and
>> for I/O. Those are shift operators, damnit; shifting has *nothing* to do
with I/O. A new operator should have been introduced to support new I/O
semantics.

However, the fact that operator overloading *can* be misused is no argument
for removing a feature from a language. Gosling weakened Java by removing
any C++ feature he deemed confusing or difficult. You don't ban hammers
because people can hit their thumbs with them...

** Scott Robert Ladd
http://www.coyotegulch.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 2000/08/21
Raw View
"Stephen Howe" <SPAMGUARDstephen.howe@dial.pipex.co.uk> wrote...
>
> Victor Bazarov <vAbazarov@dAnai.com> wrote in message
> news:8nhd91$42p$1@bob.news.rcn.net...
>
> > No, but you would expect to understand the '+' as "addition" for any
> > type defining it, wouldn't you?  Or unary '-' as negation of some
> > kind...
>
> No. Addition of strings is quite different from addition of integers.
It is
      ^^^^^^^^^^^^^^^^^^^
> what the C++ community is used to. I am sure it could get used to '+'
for
                            ^^^^^^^
> some other binary operation if it had to just as I had to get used to
>
> cout << "12";
>
> as some type of output operator and not think "left shift".

The point was that we are _used_ to some things, like, for example,
the expression (a=2,b,c++) will [most probably] mean that first
we assign 2 to a (with necessary conversions, etc.), then get the
value of b (and lose it), and then get the value of c and increment
c after that.  The [usually understood] result of this expression
is the value of c before its increment.  No?  Not in the case if
the operator, has been overloaded for types that assignment of a's
type (possibly overloaded as well) returns.  Is that good?  IMHO,
not.

I feel that introducing unusual constructs is ill-advised (even if
the language allows it).  You have snipped my other example
(a -> b == c == e) and decided to say nothing to comment.  The most
important part of what I was trying to say is that the perceived
construct so significantly different from the actual behaviour
that it makes it wrong to introduce.  (again, I have nothing against
'+' being defined as "intersection" for some geometrical classes,
although I would have to get used to it)

Victor
--
Please remove capital A's from my address when replying by mail



---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Trevor L. Jackson, III" <fullmoon@aspi.net>
Date: 2000/08/21
Raw View
Francis Glassborow wrote:

> In article <399E0C97.BC5E564B@aspi.net>, Trevor L. Jackson, III
> <fullmoon@aspi.net> writes
> >If I could be sure that the compiler would complain about under init I'd be
> >free to declare the desired array sizes without becoming vulnerable to init
> >list maintenance leaving some elements uninitialized.
>
> But they aren't, if an array has insufficient initialisers though at
> least one has been provided the extras are zero initialised. I would
> hate it if it were otherwise. To my mind the current rule is exactly
> right.

The presence of a partial initializer is irrelevant.

Zero initialization is not appropriate for all elements.  Consider pointers.

The point is that it is impossible to tell whether an array has been fully
explicitly initialized as opposed to partially explicitly initialized.  Would
you care to address the point at issue?

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/08/21
Raw View
In article <8ns2jk$dcq$1@bob.news.rcn.net>, Victor Bazarov
<vAbazarov@dAnai.com> writes
>I feel that introducing unusual constructs is ill-advised (even if
>the language allows it).  You have snipped my other example
>(a -> b == c == e) and decided to say nothing to comment.  The most
>important part of what I was trying to say is that the perceived
>construct so significantly different from the actual behaviour
>that it makes it wrong to introduce.  (again, I have nothing against
>'+' being defined as "intersection" for some geometrical classes,
>although I would have to get used to it)

Basically we should limit our provision of overloaded operators to those
that would be expected/intuitive (or almost so) for an expert in the
application domain.



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

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: Tue, 22 Aug 2000 01:44:46 GMT
Raw View
In article <39A079DC.1AA4CE4B@aspi.net>, Trevor L. Jackson, III
<fullmoon@aspi.net> writes
>Francis Glassborow wrote:
>
>> In article <399E0C97.BC5E564B@aspi.net>, Trevor L. Jackson, III
>> <fullmoon@aspi.net> writes
>> >If I could be sure that the compiler would complain about under init I'd be
>> >free to declare the desired array sizes without becoming vulnerable to init
>> >list maintenance leaving some elements uninitialized.
                                           ^^^^^^^^^^^^^
That is the point I was addressing

>>
>> But they aren't, if an array has insufficient initialisers though at
>> least one has been provided the extras are zero initialised. I would
>> hate it if it were otherwise. To my mind the current rule is exactly
>> right.
>
>The presence of a partial initializer is irrelevant.

Why, without any initialiser, if at block scope the array is
uninitialised
>
>Zero initialization is not appropriate for all elements.  Consider pointers.

Put zero initialisation (default initialisation for udts) is exactly
what I want for pointers, it sets them as null pointers.

>
>The point is that it is impossible to tell whether an array has been fully
>explicitly initialized as opposed to partially explicitly initialized.  Would
>you care to address the point at issue?

Well unless you choose to make the final initialiser indistinguishable
from zero/default initialisation, I can determine where explicit
initialisation ended.


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

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Trevor L. Jackson, III" <fullmoon@aspi.net>
Date: Tue, 22 Aug 2000 01:45:37 GMT
Raw View
Christopher Eltschka wrote:

> Michiel Salters wrote:
> >
> > [ Snipped quite a lot. MS. ]
> >
> > "llewelly."@@edevnull.dot.com wrote:
> >
> > > David R Tribble <david@tribble.com> writes:
> >
> > > >    cout << x;       // Shift x to the output?
> > > >    cout.print(x);   // Is this really less readable?
> >
> > > The principal problem with having an [io]stream::print() method is
> > >   that C++ has no type safe variable argument functions; such a print
> > >   method would have to take a fixed number of arguments, making stream
> > >   i/o quite tedious and irritating.
> >
> > > Overloading a operator<<() is used as a kind of substitute. I do not
> > >   think that << and >> are 'obvious' i/o operators, but I do think
> > >   that their use in C++ streams is just about the best overall
> > >   decision the language allows.
> >
> > The problem of no variable argument lists is as much a problem for
> > ostream::print() as it is for ostream::operator<<(), that is, no
> > problem at all. But I'd call it ostream::pr() to shorten it:
> >
> > cout.pr("The price is ").pr(5).pr(" dollar and ").pr(52).pr("Cents");
>
> What about overloading just operator():
>
> cout ("The price is ") (5) (" dollar and ") (52) (" Cents.");

It only works in one direction.  What would you do for input?  Remember there
are bi-directional streams, so the type of the left operand can't be used to
resolve direction.

Perhaps the next least likely operators( after << and >>)  to apply to a
stream is && and ||.  Which would you prefer to indicate input? *NOT!*

>
>
> Seens quite readable to me. Indeed, I think an implementation
> could allow this as extension (I don't think this syntax is
> currently allowed). To provide maximum compatibility,
> ostream::operator() would be implemented as
>
> template<class T>
>  ostream& ostream::operator()(T const& t)
> {
>   return *this << t;
> }
>
> (actually, this would be in basic_ostream<...>, of course)
>
> [...]
>
> ---
> [ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Trevor L. Jackson, III" <fullmoon@aspi.net>
Date: Tue, 22 Aug 2000 01:45:15 GMT
Raw View
Victor Bazarov wrote:

> "Stephen Howe" <SPAMGUARDstephen.howe@dial.pipex.co.uk> wrote...
> >
> > Victor Bazarov <vAbazarov@dAnai.com> wrote in message
> > news:8nhd91$42p$1@bob.news.rcn.net...
> >
> > > No, but you would expect to understand the '+' as "addition" for any
> > > type defining it, wouldn't you?  Or unary '-' as negation of some
> > > kind...
> >
> > No. Addition of strings is quite different from addition of integers.
> It is
>       ^^^^^^^^^^^^^^^^^^^
> > what the C++ community is used to. I am sure it could get used to '+'
> for
>                             ^^^^^^^
> > some other binary operation if it had to just as I had to get used to
> >
> > cout << "12";
> >
> > as some type of output operator and not think "left shift".
>
> The point was that we are _used_ to some things, like, for example,
> the expression (a=2,b,c++) will [most probably] mean that first
> we assign 2 to a (with necessary conversions, etc.), then get the
> value of b (and lose it), and then get the value of c and increment
> c after that.  The [usually understood] result of this expression
> is the value of c before its increment.  No?  Not in the case if
> the operator, has been overloaded for types that assignment of a's
> type (possibly overloaded as well) returns.  Is that good?  IMHO,
> not.
>
> I feel that introducing unusual constructs is ill-advised (even if
> the language allows it).  You have snipped my other example
> (a -> b == c == e) and decided to say nothing to comment.  The most
> important part of what I was trying to say is that the perceived
> construct so significantly different from the actual behaviour
> that it makes it wrong to introduce.  (again, I have nothing against
> '+' being defined as "intersection" for some geometrical classes,
> although I would have to get used to it)

This is a reasonable position, but I believe it ignores some frequency issues
that lend weight to the opposing viewpoint.  In my experience the classical
comma operator is rarely used.  Certainly is is one of the last operators that
a journeyman programmer needs to learn in order to use C/C++ effectively.

OTOH, array initialization is reasonably common.  Certainly it is something
that a competent programmer must master.

If it were necessary to completely eliminate the classical comma operator in
order to make it available for array initialization I suspect it would be a
reasonable tradeoff.  But since we do not need to eliminate the classical
comma operator in order to use the array init operator, the only thing
forbidding it is inertia.  If the value of the new usage is larger than the
value of the classical usage, then we should accept the idiom as worth
learning.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Trevor L. Jackson, III" <fullmoon@aspi.net>
Date: 2000/08/22
Raw View
Francis Glassborow wrote:

> In message <39A079DC.1AA4CE4B@aspi.net>, Trevor L. Jackson, III
> <fullmoon@aspi.net> writes
> >> In article <399E0C97.BC5E564B@aspi.net>, Trevor L. Jackson, III
> >> <fullmoon@aspi.net> writes
> >> >If I could be sure that the compiler would complain about under init I'd be
> >> >free to declare the desired array sizes without becoming vulnerable to init
> >> >list maintenance leaving some elements uninitialized.
>                                            ^^^^^^^^^^^^^
>
> That is what you wrote, and that can only be the case if no
> initialisation takes place.

In the context of the discussion I thought it obvious that I did not consider
clearing to zero to be initialization.  Granted, you don't get a core constant as
with a classical uninitialized variable.  But setting all core constants to zero is
not a answer to the problem.

>
>
> >>
> >> But they aren't, if an array has insufficient initialisers though at
> >> least one has been provided the extras are zero initialised. I would
> >> hate it if it were otherwise. To my mind the current rule is exactly
> >> right.
> >
> >The presence of a partial initializer is irrelevant.
>
> Not in what I was commenting on.

Yes.  Even if no initializer is present the elements that are not explicitly
initialized (all of them in this case) get cleared to zero.

>
> >
> >Zero initialization is not appropriate for all elements.  Consider pointers.
> So? Pointers can be zero initialised (they become null pointers)
>
> >
> >The point is that it is impossible to tell whether an array has been fully
> >explicitly initialized as opposed to partially explicitly initialized.  Would
> >you care to address the point at issue?
>
> It is only impossible to determine if you explicitly zero initialise the
> last element you provide an initialiser for, or you are using types fore
> which zero initialisation cannot be tested for, which are a pretty
> specialist subset of all types.

Hardly.  Many so called little languages require a descriptor for each element of
the language.  In Lisp and Windows(!tm) it is typical to to perform the gathering
of constant values at run time.  Consing up a list is natural in Lisp.  Using
run-time assignment to initialize data structures that should be (1) initialized
and checked at run time, and (2) const, is typical of the Really Bad Software that
is the essence of Windows(!tm).  It is unnatural use of C/C++.

In C/C++ it is natural to initialize the list of pre-defined elements of the
language at compile time.  It is hardly useful to have some number of those
elements the target of memset( array_tail, '0', ...);

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Trevor L. Jackson, III" <fullmoon@aspi.net>
Date: 2000/08/22
Raw View
Victor Bazarov wrote:

> "Trevor L. Jackson, III" <fullmoon@aspi.net> wrote...

[snip]

> >
> > Funny you should mention this example.  I agree that operators should not
> > surprise their users.  But a couple months ago I asked exactly this
> question
> > regarding using <<, <<=, >> amd >>= as relational operators.  My concern
> was
> > the strength of the presumption on the part of the average reader.
> >
> > Now if you came across code like this:
> >
> >     void func( UDT const & value, UDT const & limit )    // You can assume
> a
> > UDT is a complex numeric type
> >     {
> >         if ( X <<= Y ) {
> >             /* Munch on X */
> >         }
> >     }
> >
> > ... would it really be that confusing?
>
> Well, er, it would.  What *are* X and Y?  Did you mean to say
>
>         if ( value <<= limit ) {
>             /* Munch on value */
>         }
>
> And even in that case, I don't understand the meaning of <<=.

OK, I did not mean to imply that the meaning should be obvious by inspection,
but even with no comprehension of value, limit (or even abstract X and &), and
the <<= operator there's enough context to infer that <<= is a relational
operator over the type UDT.

>
>
> In mathematics I learned, '<<' meant "much less than".  What
> does equal sign do to that expression?
>
> Are we talking of the same thing here?

I guess not.  Given a UDT where using the relational operators <, >, <= amd >=
involve some stretching, one might avoid them in order to avoid surprising a
reader with the stretched meanings.  It appears to me to be safer to define
relational operators <<, >>, <<= and >>= that are suggestive of the original
operators.  A reader will know immediately that there is something unusual about
the relationships expressed.  If interested enough he can check the definitions.

In the particular example I mentioned the property is not "much" but
"completely".  So << means completely less than rather than the classical
mathematical notation of much less than.  The operator <<= is not useful in the
context of "much", but perfectly reasonable in the context of "completely" in
that <<= is the analogue for the classical .LE. operator <=.  Note that the
"completely" operators also share the classical complement relationships in
which << is the complement of >>= and <<= is the complement of >> just as is the
case for </>= and <<=/>.

[snip]

> > Agreed.  But the context, which is typically limited to initialization, is
> > going to give a reasonable hint to the reader.  I suppose that I prefer
> the
> > first of these two alternatives for reasons of readability:
> >
> >     array_t A = 1, 2, 3, 4, 5;
> >     array_t A, 1, 2, 3, 4, 5;
>
> Actually, it is impossible to do because the declaration above
> does NOT invoke the comma operator.

You are right.  I wrote too quickly.

>  You are confusing it with
> assignment
>
>     array_t A;
>     A = 1, 2, 3, 4, 5; // here the comma operator is used.
>     array_t A = 1, 2;  // this is syntax error - int constant
>                        // in a declarator list.
>
> >
> > ... which brings up another alternative: overloading the assignment
> operator
> > to perform incremental initialization.  Would you find
> >
> >     array_t A = 1 = 2 = 3 = 4 = 5;
> >
> > ... to be as confusing?  To me the sequence looks less like a list of
> values
> > that the comma delimited init above.
>
> I agree that the comma may look better.  What I would like to have
> in the language is an ability to declare a constant that means
> "array of", like in
>
>     array_t A = { 1,2,3,4 }; // the '{ ... }' should be treated
>                              // as an array of ints just like
>                              // '"abcd"' is treated as an array
>                              // of chars.

Why stop there?  In principle there should be a literal expression that
corresponds to every possible POD type.  Declaring struct S { int s_I; double
s_D, char const *s_P } should permit
literalsl of the form...

        struct S example;
        example = { 0, -1.0, "empty" };

>
>
> considering that the class array_t is defined as
>
> class array_t
> {
>     ...
> public:
>     array_t(int a[]) { ... use the array, AND KNOW ITS SIZE TOO ... }
>     ...
> };
>
> The distinction between _an_array_of_T_ and _a_pointer_to_T_ is
> invaluable for those who deal with vectors, tensors, matrices, etc.
>
> It would bring up, of course, such difficult topics like ability to
> assign arrays, convert arrays to something else...  I understand
> that it probably was the reason the arrays were NOT made a fully
> capable element of the language.  I probably need to read more on
> the design and evolution...

I suspect you'd need a formal array descriptor as is available in some languages
(ALGOL, etc.)  Since C has few constructs that are not native to fairly basic
instruction sets I doubt we'll see anything like this soon.  Also the existence
of STL satisfies some of the demand for more convenient array support.


---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/08/22
Raw View
"Trevor L. Jackson, III" wrote:
>
> Christopher Eltschka wrote:
>
> > Michiel Salters wrote:
> > >
> > > [ Snipped quite a lot. MS. ]
> > >
> > > "llewelly."@@edevnull.dot.com wrote:
> > >
> > > > David R Tribble <david@tribble.com> writes:
> > >
> > > > >    cout << x;       // Shift x to the output?
> > > > >    cout.print(x);   // Is this really less readable?
> > >
> > > > The principal problem with having an [io]stream::print() method is
> > > >   that C++ has no type safe variable argument functions; such a print
> > > >   method would have to take a fixed number of arguments, making stream
> > > >   i/o quite tedious and irritating.
> > >
> > > > Overloading a operator<<() is used as a kind of substitute. I do not
> > > >   think that << and >> are 'obvious' i/o operators, but I do think
> > > >   that their use in C++ streams is just about the best overall
> > > >   decision the language allows.
> > >
> > > The problem of no variable argument lists is as much a problem for
> > > ostream::print() as it is for ostream::operator<<(), that is, no
> > > problem at all. But I'd call it ostream::pr() to shorten it:
> > >
> > > cout.pr("The price is ").pr(5).pr(" dollar and ").pr(52).pr("Cents");
> >
> > What about overloading just operator():
> >
> > cout ("The price is ") (5) (" dollar and ") (52) (" Cents.");
>
> It only works in one direction.  What would you do for input?  Remember there
> are bi-directional streams, so the type of the left operand can't be used to
> resolve direction.

class istream: ...
{
public:
  istream& in;
  istream(): in(*this) ... { ... }
  // ...
};

class ostream: ...
{
public:
  ostream& out
  ostream(): out(*this) ...
};

class iostream: public istream, public ostream
{
// ...
};

iostream str;
int i;

str.out ("Input a number: ");
str.in (i);

cout (foo); would be equivalent toi cout.out (foo);
cin (foo); would be equivalent to cin.in (foo);

for iostream, you'd have to explicitly specify in or out

>
> Perhaps the next least likely operators( after << and >>)  to apply to a
> stream is && and ||.  Which would you prefer to indicate input? *NOT!*

I wouldn't consider || and && for input/output. If normal binary
operators are to be used, << and >> are probably the best choice.

But operator() would have some advantages:

- No problems with operator precedence (errors like
  cout << a==b << endl; are easy to make - cout (a==b) (endl);
  would be foolproof in this respect)
- IMHO more readable

BTW, as member function template, it would have the added advantage
to be callable on rvalues:

ostringstream(line).out (a) (b) (c);

BTW, && and || _can_ be applied to streams:

if (cin && cout) // if neither input nor output failed
  do_something_with(cin, cout);

[...]

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 2000/08/22
Raw View
"Trevor L. Jackson, III" <fullmoon@aspi.net> wrote...
> If it were necessary to completely eliminate the classical comma operator
in
> order to make it available for array initialization I suspect it would be
a
> reasonable tradeoff.  But since we do not need to eliminate the classical
> comma operator in order to use the array init operator, the only thing
> forbidding it is inertia.  If the value of the new usage is larger than
the
> value of the classical usage, then we should accept the idiom as worth
> learning.

There is a delicate balance in the world between following common
sense and breaking off the inertia.  On one hand, the latter is
necessary to ensure change and hence progress.  However, the former
keeps us from swinging too wildly from one extreme to another.

I suppose, since the OP asked about a good example of overloading
the comma operator the entire dispute is about the definition of
'good'.  Is it good to try to define good?  Can there be a common
definition for good?

BTW, I mentioned very by-the-way-ishly something that the present
discussion brought up.  There is a special kind of constant called
string literal.  However, we seem to always treat it as an array of
chars.  Why don't we have an array const?  What if we made the
language to accept syntax {1,2,3} as an array of three integers?
The absence of real arrays (that *are* objects, whose size is
*always* known) seem to debilitate the language.  Don't you think?
Or, there is another extreme: down with arrays, we have the vector
template now, that is so much more than just an array...  I seem
to be needing a good course on language design.  I'll be going now...

Victor
--
Please remove capital A's from my address when replying by mail



---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/08/22
Raw View
In article <39A1B58E.5497638A@aspi.net>, Trevor L. Jackson, III
<fullmoon@aspi.net> writes
>Yes.  Even if no initializer is present the elements that are not explicitly
>initialized (all of them in this case) get cleared to zero.

Untrue, for builtin types and such things as pointers, nothing is done
unless the object is at namespace scope. For udt's their default ctor is
called, which might also do nothing.


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

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/08/22
Raw View
In article <39A1B58E.5497638A@aspi.net>, Trevor L. Jackson, III
<fullmoon@aspi.net> writes
>In C/C++ it is natural to initialize the list of pre-defined elements of the
>language at compile time.  It is hardly useful to have some number of those
>elements the target of memset( array_tail, '0', ...);

That is not what zero-initialisation means. It never has been, AFAIK.

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

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: kanze@gabi-soft.de
Date: 2000/08/23
Raw View
Gabriel Dos Reis <gdr@merlin.codesourcery.com> writes:

|>  kanze@gabi-soft.de writes:

|>  | Michiel Salters <salters@lucent.com> writes:

|>  | |>  The problem with this syntax is that it's not simply
|>  | |>  extensible, you can't add ostream.pr(MyClass).

|>  | Of course you can, now.  ostream::pr is a template member function
|>  | for which the user can (must?) provide a specialization.  (A
|>  | potential problem is that no user defined conversions would be
|>  | considered.)

|>  At a first glance, I think that approach isn't very appealing: if
|>  the specialization is missing then the primary template will be
|>  selected; at best one gets a link-time error instead of compile-time
|>  error.  Of course, that problem is easily worked around with:

Or just don't provide a primary template:-).

Of course, given the current situation, my solution was to provide a
primary template which used operator<< for the formatting (after having
set the format flags according to the format specifier).  Thus, I
automatically leverage off of all of the "standard" conversion routines
that people have written.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david@tribble.com>
Date: 2000/08/23
Raw View
Scott Robert Ladd wrote:
> However, the fact that operator overloading *can* be misused is no
> argument for removing a feature from a language. Gosling weakened
> Java by removing any C++ feature he deemed confusing or difficult.
> You don't ban hammers because people can hit their thumbs with them...

Or pointers?  ;-)

Actually, rather than taking out features, Gosling didn't add in any
features unless he thought there was a need for them.  He was using
ideas from C++, Eiffel, SmallTalk, etc.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david@tribble.com>
Date: 2000/08/25
Raw View
Victor Bazarov wrote:
> [...]
> I agree that the comma may look better.  What I would like to have
> in the language is an ability to declare a constant that means
> "array of", like in
>
>     array_t A = { 1,2,3,4 }; // the '{ ... }' should be treated
>                              // as an array of ints just like
>                              // '"abcd"' is treated as an array
>                              // of chars.
>
> considering that the class array_t is defined as
>
> class array_t
> {
>     ...
> public:
>     array_t(int a[]) { ... use the array, AND KNOW ITS SIZE TOO ... }
>     ...
> };
>
> The distinction between _an_array_of_T_ and _a_pointer_to_T_ is
> invaluable for those who deal with vectors, tensors, matrices, etc.
>
> It would bring up, of course, such difficult topics like ability to
> assign arrays, convert arrays to something else...  I understand
> that it probably was the reason the arrays were NOT made a fully
> capable element of the language.  I probably need to read more on
> the design and evolution...

C99 has added the ability to pass an array and have the called
function receive the size of the array.  (I don't know the details,
however; see 6.7.5.3 of C99.)  Maybe C++ will add this feature some
day.

You can get the size of array objects using templates, e.g.:

    template <int N>
    void foo(int a[N])
    {
        ... a has N elements ...
    }

The drawback is that this function gets instantiated for every
possible array size passed to foo<>().

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david@tribble.com>
Date: 2000/08/25
Raw View
"Trevor L. Jackson, III" wrote:
> [...]
> The point is that it is impossible to tell whether an array has been
> fully explicitly initialized as opposed to partially explicitly
> initialized.  Would you care to address the point at issue?

FWIW, C99 has designated initializers, so that you could ensure that
all of the elements of an array are initialized:

    int  arr[N] = { 1, 2, [N-1] = 0 };

All of the elements of arr are initialized; arr[0], arr[1], and
arr[N-1] are explicitly initialized, while all the rest (i.e., those
between arr[1] and arr[N-1]) are default (zero) initialized.

Perhaps C++ will add this feature in the future.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Hicham BOUHMADI" <hicham@citeweb.net>
Date: 2000/08/16
Raw View
Hi,
There is many features in the C++ that are not exploited enough...
one of those feature are the overloading of the ',' operator.

Is there anyone who has a 'good' and 'usefull' example of this feature?

Thanks

Hicham BOUHMADI            hicham@citeweb.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "E. Robert Tisdale" <edwin@netwood.net>
Date: 2000/08/16
Raw View
Hicham BOUHMADI wrote:

> There is many features in the C++ that are not exploited enough...
> one of those feature are the overloading of the ',' operator.
>
> Is there anyone who has a 'good' and 'usefull' example of this feature?

Take a look at Blitz++

    http://www.oonumerics.org/blitz/

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 2000/08/16
Raw View
"E. Robert Tisdale" <edwin@netwood.net> wrote...
> Hicham BOUHMADI wrote:
>
> > There is many features in the C++ that are not exploited enough...
> > one of those feature are the overloading of the ',' operator.
> >
> > Is there anyone who has a 'good' and 'usefull' example of this
feature?
>
> Take a look at Blitz++
>
>     http://www.oonumerics.org/blitz/

I did.  And I have questions.  Can you tell me how it is possible
to use "list initialiser" in the form

    Array<int,1> A(3);
    A = 1, 0, 1;

when operator comma has LOWER precedence than assignment operator
(and the precedence cannot be changed by overloading)?

As far as my poor knowledge of C++ is concerned, the statement
should be interpreted as "(A = 1), NOP, NOP;" which is "A = 1;".

Please give me a hand here.

Thank you.

Victor
--
Please remove capital A's from my address when replying by mail



---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/08/16
Raw View
In article <8ne827$8dd$1@reader1.imaginet.fr>, Hicham BOUHMADI
<hicham@citeweb.net> writes
>Hi,
>There is many features in the C++ that are not exploited enough...
>one of those feature are the overloading of the ',' operator.
>
>Is there anyone who has a 'good' and 'usefull' example of this feature?

I really hope not:) Funnily enough I commented today to those attending
an advanced C++ course I am presenting  that just because something can
be done is no justification for doing it.  There are lots of things that
can be done in C++ that are much better avoided if you want to write
good code.


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

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "E. Robert Tisdale" <edwin@netwood.net>
Date: 2000/08/16
Raw View
Victor Bazarov wrote:

> "E. Robert Tisdale" <edwin@netwood.net> wrote...
> > Hicham BOUHMADI wrote:
> >
> > > There is many features in the C++ that are not exploited enough...
> > > one of those feature are the overloading of the ',' operator.
> > >
> > > Is there anyone who has a 'good' and 'usefull' example of this
> feature?
> >
> > Take a look at Blitz++
> >
> >     http://www.oonumerics.org/blitz/
>
> I did.  And I have questions.  Can you tell me how it is possible
> to use "list initialiser" in the form
>
>     Array<int,1> A(3);
>     A = 1, 0, 1;
>
> when operator comma has LOWER precedence than assignment operator
> (and the precedence cannot be changed by overloading)?
>
> As far as my poor knowledge of C++ is concerned, the statement
> should be interpreted as "(A = 1), NOP, NOP;" which is "A = 1;".
>
> Please give me a hand here.

C'mon Victor,

A = 1 sets the first element of array A to 1
--> and returns an expression object <--
so that we now have

    expression(A = 1), 0, 1;

expression(A = 1), 0 sets the second element of A to 0
--> and returns another expression object <--
so that we now have

    expression(expression(A = 1), 0), 1;

which sets the third element of A to 1
--> and returns yet another expression object <--
which might, I suppose, be cast into a reference to array A.
The Blitz++ developers implement all this
with (inline) expressions which the compiler optimizes away
so that the full expression is equivalent to

    A[0] = 1; A[1] = 0; A[2] = 1;

Is this useful?  I don't know.  I'll let you judge.
To me, at least, it does appear to make the code more readable.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 2000/08/16
Raw View
"E. Robert Tisdale" <edwin@netwood.net> wrote...
> Victor Bazarov wrote:
>
> > "E. Robert Tisdale" <edwin@netwood.net> wrote...
> > > Hicham BOUHMADI wrote:
> > >
> > > > There is many features in the C++ that are not exploited
enough...
> > > > one of those feature are the overloading of the ',' operator.
> > > >
> > > > Is there anyone who has a 'good' and 'usefull' example of this
> > feature?
> > >
> > > Take a look at Blitz++
> > >
> > >     http://www.oonumerics.org/blitz/
> >
> > I did.  And I have questions.  Can you tell me how it is possible
> > to use "list initialiser" in the form
> >
> >     Array<int,1> A(3);
> >     A = 1, 0, 1;
> >
> > when operator comma has LOWER precedence than assignment operator
> > (and the precedence cannot be changed by overloading)?
> >
> > As far as my poor knowledge of C++ is concerned, the statement
> > should be interpreted as "(A = 1), NOP, NOP;" which is "A = 1;".
> >
> > Please give me a hand here.
>
> C'mon Victor,
>
> A = 1 sets the first element of array A to 1
> --> and returns an expression object <--
> so that we now have
>
>     expression(A = 1), 0, 1;
>
> expression(A = 1), 0 sets the second element of A to 0
> --> and returns another expression object <--
> so that we now have
>
>     expression(expression(A = 1), 0), 1;
>
> which sets the third element of A to 1
> --> and returns yet another expression object <--
> which might, I suppose, be cast into a reference to array A.

I read the source, I understood what it did.  THAT was not the
problem.  The problem is to convince me that what's going on is
right.

> The Blitz++ developers implement all this
> with (inline) expressions which the compiler optimizes away
> so that the full expression is equivalent to
>
>     A[0] = 1; A[1] = 0; A[2] = 1;
>
> Is this useful?  I don't know.  I'll let you judge.
> To me, at least, it does appear to make the code more readable.

To me it doesn't.  Namely because the assignment has the higher
precedence.

The expression
    <variable> = <value>, <value>, <value>
does NOT mean
    <variable> := SOMECOMBINATIONOF(<value>,<value>,<value>)
to me.

The LANGUAGE, while allowing for such strange constructs, should
NOT be used in such way, IMHO.

I can understand
    A(1, 0, 1); // some kind of freaky function call (through '...')
but not what they did.  However KEWL they might consider it.

Victor
--
Please remove capital A's from my address when replying by mail



---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: alexo@bigfoot---filter---.com (Alex Oren)
Date: 2000/08/17
Raw View
On Wed, 16 Aug 2000 20:27:34 GMT, "Victor Bazarov" <vAbazarov@dAnai.com>
wrote:

} "E. Robert Tisdale" <edwin@netwood.net> wrote...
} > Hicham BOUHMADI wrote:
} >
} > > There is many features in the C++ that are not exploited enough...
} > > one of those feature are the overloading of the ',' operator.
} > >
} > > Is there anyone who has a 'good' and 'usefull' example of this
} feature?
} >
} > Take a look at Blitz++
} >
} >     http://www.oonumerics.org/blitz/
}
} I did.  And I have questions.  Can you tell me how it is possible
} to use "list initialiser" in the form
}
}     Array<int,1> A(3);
}     A = 1, 0, 1;
}
} when operator comma has LOWER precedence than assignment operator
} (and the precedence cannot be changed by overloading)?
}
} As far as my poor knowledge of C++ is concerned, the statement
} should be interpreted as "(A = 1), NOP, NOP;" which is "A = 1;".
}
} Please give me a hand here.

I think that

 A = 1, 0, 1;

translates to

 A.operator=(1).operator,(0).operator,(1);

All operators are overloaded.


Have fun,
Alex.

--
My email address is intentionally mangled to foil spambots.
Please remove the "---filter---" from the address for replying.
Sorry for the inconvenience.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Pierre Aubert <paubert@pcmath03.insa-lyon.fr>
Date: 2000/08/17
Raw View
"Hicham BOUHMADI" <hicham@citeweb.net> writes:

> Hi,
> There is many features in the C++ that are not exploited enough...
> one of those feature are the overloading of the ',' operator.
>
> Is there anyone who has a 'good' and 'usefull' example of this feature?

Hi,
I have another question relative to this one. If something like

Array<2,double> a(2,2) = 1,2,3,4;

works, how can we make a working operator, for

Array<2,double> const a(2,2) = 1,2,3,4;
                ^^^^^

???

--
Pierre Aubert.              Pierre.Aubert@insa-lyon.fr
tel: +33 (0) 4 72 43 89 16  http://pcmath03.insa-lyon.fr/~paubert/
fax: +33 (0) 4 72 43 85 29  MAPLY, UMR 5585 CNRS && INSA-Lyon

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Trevor L. Jackson, III" <fullmoon@aspi.net>
Date: 2000/08/17
Raw View
Victor Bazarov wrote:

> "E. Robert Tisdale" <edwin@netwood.net> wrote...
> > Victor Bazarov wrote:
> >
> > > "E. Robert Tisdale" <edwin@netwood.net> wrote...
> > > > Hicham BOUHMADI wrote:
> > > >
> > > > > There is many features in the C++ that are not exploited
> enough...
> > > > > one of those feature are the overloading of the ',' operator.
> > > > >
> > > > > Is there anyone who has a 'good' and 'usefull' example of this
> > > feature?
> > > >
> > > > Take a look at Blitz++
> > > >
> > > >     http://www.oonumerics.org/blitz/
> > >
> > > I did.  And I have questions.  Can you tell me how it is possible
> > > to use "list initialiser" in the form
> > >
> > >     Array<int,1> A(3);
> > >     A = 1, 0, 1;
> > >
> > > when operator comma has LOWER precedence than assignment operator
> > > (and the precedence cannot be changed by overloading)?
> > >
> > > As far as my poor knowledge of C++ is concerned, the statement
> > > should be interpreted as "(A = 1), NOP, NOP;" which is "A = 1;".
> > >
> > > Please give me a hand here.
> >
> > C'mon Victor,
> >
> > A = 1 sets the first element of array A to 1
> > --> and returns an expression object <--
> > so that we now have
> >
> >     expression(A = 1), 0, 1;
> >
> > expression(A = 1), 0 sets the second element of A to 0
> > --> and returns another expression object <--
> > so that we now have
> >
> >     expression(expression(A = 1), 0), 1;
> >
> > which sets the third element of A to 1
> > --> and returns yet another expression object <--
> > which might, I suppose, be cast into a reference to array A.
>
> I read the source, I understood what it did.  THAT was not the
> problem.  The problem is to convince me that what's going on is
> right.
>
> > The Blitz++ developers implement all this
> > with (inline) expressions which the compiler optimizes away
> > so that the full expression is equivalent to
> >
> >     A[0] = 1; A[1] = 0; A[2] = 1;
> >
> > Is this useful?  I don't know.  I'll let you judge.
> > To me, at least, it does appear to make the code more readable.
>
> To me it doesn't.  Namely because the assignment has the higher
> precedence.
>

If assignment had lower precedence it would not work.

It's an idiom.  You don't expect to read idioms literally.  Since A is an
array, and arrays are typically the address of their first element, you can
interpret A as such a pointer.  The expression is equivalent to:

    *A++ = 1, *A++ = 0, *A++ = 1;

... which is pretty clearly filling in an array.


>
> The expression
>     <variable> = <value>, <value>, <value>
> does NOT mean
>     <variable> := SOMECOMBINATIONOF(<value>,<value>,<value>)
> to me.
>
> The LANGUAGE, while allowing for such strange constructs, should
> NOT be used in such way, IMHO.
>
> I can understand
>     A(1, 0, 1); // some kind of freaky function call (through '...')
> but not what they did.  However KEWL they might consider it.

Do you have the same difficulty with:

    cout << 1 << 0 << 1;

... It's the same kind of idiom.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david@tribble.com>
Date: 2000/08/17
Raw View
Hicham BOUHMADI <hicham@citeweb.net> writes
>> There is many features in the C++ that are not exploited enough...
>> one of those feature are the overloading of the ',' operator.
>>
>> Is there anyone who has a 'good' and 'usefull' example of this
>> feature?

Francis Glassborow wrote:
> I really hope not:) Funnily enough I commented today to those
> attending an advanced C++ course I am presenting  that just because
> something can be done is no justification for doing it.  There are
> lots of things that can be done in C++ that are much better avoided
> if you want to write good code.

In the July 2000 issue of "The Java Report", in an interview with
James Gosling, Dennis Ritchie, and Bjarne Stroustrup, Gosling
describes the reasons he didn't add operator overloading to Java:

   ...
   Probably about 20% to 30% of the population think of operator
   overloading as the spawn of the devil; ...  A lot of that stems
   from the fact that there are only about half a dozen operators
   you can sensibly overload, and yet there are thousands or
   millions of operators that people would like to define - so you
   have to pick, and often the choices conflict with your sense of
   intuition.

   Then there's a community of about 10% that have actually used
   operator overloading appropriately and who really care about it,
   and for whom it's actually really important; this is almost
   exclusively people who do numerical work, where the notation is
   very important to appealing to people's intuition, because they
   come into it with an intuition about what the + means, and the
   ability to say "a + b" where a and b are complex number or
   matrices or something really does make sense.  You get kind of
   shaky when you get to things like multiply because there are
   actually multiple kinds of multiplication operators - there's
   vector product, and dot product, which are fundamentally
   different.  And yet there's only one operator, so what do you do?
   And there's no operator for square root.

   Those two camps are the poles, and then there's this mush in the
   middle of 60-odd% who really couldn't care much either way.

The Blitz++ library is an example of the numerical folk who can
use operator overloading to their advantage.  But outside the domain
of numerical applications, I personally find operator overloading
to be more confusing than using regular functions.

   cout << x;       // Shift x to the output?
   cout.print(x);   // Is this really less readable?

   cin >> x;        // Shift input into x; or is it x << cin?
   cin.scan(&x);    // Does this hurt?

My opinion is to avoid operator overloading whenever possible,
especially the more confusing operators like: , ^ << >>.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: llewelly.@@edevnull.dot.com
Date: Fri, 18 Aug 2000 02:22:10 GMT
Raw View
David R Tribble <david@tribble.com> writes:

> Hicham BOUHMADI <hicham@citeweb.net> writes
> >> There is many features in the C++ that are not exploited enough...
> >> one of those feature are the overloading of the ',' operator.
> >>
> >> Is there anyone who has a 'good' and 'usefull' example of this
> >> feature?
>
> Francis Glassborow wrote:
> > I really hope not:) Funnily enough I commented today to those
> > attending an advanced C++ course I am presenting  that just because
> > something can be done is no justification for doing it.  There are
> > lots of things that can be done in C++ that are much better avoided
> > if you want to write good code.
>
> In the July 2000 issue of "The Java Report", in an interview with
> James Gosling, Dennis Ritchie, and Bjarne Stroustrup, Gosling
> describes the reasons he didn't add operator overloading to Java:
>
[snipped quote from Gosling interview]

As for java not having operator overloading, think about how operator=()
  and operator==() work on UDTs in that language; they are operations on
  *references*  -  which could lead to some very confusing examples if
  a UDT overloaded operator+=() and operator+(). How could they be
  implemented so that x+=1 and x=x+1 would be equivalent? I have no
  idea whether Gosling thinks this is an important problem, but it is
  something I had trouble with when I used an 'extended java' that
  supported operator overloading.

In C++, objects can be refered to directly; we have auto, so the above
  problem does not (usually) occur.

I point this out because I think each langauge feature must be
  considered in the context of other language features; the existence
  of feature x may make feature y confusing, error prone, or useless.

(For another example, C++ has some nasty interactions between
  pointer arithmetic (sometimes mistakenly called 'arrays' :-) and
  polymorphic types.)

I think the expressiveness of C++ templates would reduced if C++ did
  not have operator overloading; specializations for built in types
  would be necessary for many templated types that do not need them
  now. IOWs, I think operator overloading is almost necessary for
  templates to fill the needs they were intended to fill. Again, this
  is a result of the interaction of language features.

>
> The Blitz++ library is an example of the numerical folk who can
> use operator overloading to their advantage.  But outside the domain
> of numerical applications, I personally find operator overloading
> to be more confusing than using regular functions.
>
>    cout << x;       // Shift x to the output?
>    cout.print(x);   // Is this really less readable?

The principal problem with having an [io]stream::print() method is
  that C++ has no type safe variable argument functions; such a print
  method would have to take a fixed number of arguments, making stream
  i/o quite tedious and irritating.

Overloading a operator<<() is used as a kind of substitute. I do not
  think that << and >> are 'obvious' i/o operators, but I do think
  that their use in C++ streams is just about the best overall
  decision the language allows.

>
>    cin >> x;        // Shift input into x; or is it x << cin?
>    cin.scan(&x);    // Does this hurt?
>
> My opinion is to avoid operator overloading whenever possible,
> especially the more confusing operators like: , ^ << >>

operator overloading is just another way to give a function a name. If
  an operator symbol is a good name, use it. I think most of the
  arguments for and against operator overloading (the java-specific
  argument I posted above being the only exception I can think of) can
  be reduced this; most of the disagreement seems to be about what
  constitutes a 'good' name. Culture plays an important role here;
  those with a background in unix shell scripting often find <<
  and >> to reasonable names for i/o operators. I have seen those new
  to C/C++ terribly confused to find that '*p' means 'get the thing
  that p points at'. (Can anyone name a numerical lib that uses '*'
  for dot product?)

On a different note, I have noticed that the types for which
  overloaded operators seem appropriate are usually *not*
  polymorphic. In particular, the oft-mentioned classes for
  representing numerical types are usually concrete types, as are most
  smart pointer types. (The stream classes are a notable exception.)

It is also hard to guarantee that expressions like a+b retain their
  expected symetry when a and b are polymorphic.

It seems to me that operator overloading (as it is implemented in C++,
  anyway) is not really a part of OOP - it seems intended for a
  slightly different paradigm, and seldom appropriate for OOP desgins.

(Note: If I say that a feature is non-OOP, or does not interact well
  with polymorphism, that should not be construed to mean a I think
  that feature is bad; I love operator overloading, and I believe
  pointer arithmetic has an important place in low level code, and in
  inspiring STL iterators.)
p
[snip]

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Michiel Salters <salters@lucent.com>
Date: 2000/08/18
Raw View
[ Snipped quite a lot. MS. ]

"llewelly."@@edevnull.dot.com wrote:

> David R Tribble <david@tribble.com> writes:

> >    cout << x;       // Shift x to the output?
> >    cout.print(x);   // Is this really less readable?

> The principal problem with having an [io]stream::print() method is
>   that C++ has no type safe variable argument functions; such a print
>   method would have to take a fixed number of arguments, making stream
>   i/o quite tedious and irritating.

> Overloading a operator<<() is used as a kind of substitute. I do not
>   think that << and >> are 'obvious' i/o operators, but I do think
>   that their use in C++ streams is just about the best overall
>   decision the language allows.

The problem of no variable argument lists is as much a problem for
ostream::print() as it is for ostream::operator<<(), that is, no
problem at all. But I'd call it ostream::pr() to shorten it:

cout.pr("The price is ").pr(5).pr(" dollar and ").pr(52).pr("Cents");

The problem with this syntax is that it's not simply extensible, you can't
add ostream.pr(MyClass). This is a theoretical problem, though:
ostream::pr(T) would just call user_defined_print(ostream&, T).
The only problem would be that this might require partial specialization
of member functions, I think, to make ostream::pr(int) a special
case.

Still, avoiding variable argument lists isn't the killer argument for
operator<<() IMHO.

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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: youngmm@wku.edu (Mark M. Young)
Date: 2000/08/18
Raw View
On what file and line did you find that 'operator,' code?

Mark M. Young

On Wed, 16 Aug 2000 23:22:54 GMT, "Victor Bazarov"
<vAbazarov@dAnai.com> wrote:

>> > >
>> > > Take a look at Blitz++
>> > >
>> > >     http://www.oonumerics.org/blitz/
>> >
>> > I did.  And I have questions.  Can you tell me how it is possible
>> > to use "list initialiser" in the form
>> >
>> >     Array<int,1> A(3);
>> >     A = 1, 0, 1;

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 2000/08/18
Raw View
"Trevor L. Jackson, III" <fullmoon@aspi.net> wrote...
> Victor Bazarov wrote:
>
> > "E. Robert Tisdale" <edwin@netwood.net> wrote...
> > > Victor Bazarov wrote:
> > >
> > > > "E. Robert Tisdale" <edwin@netwood.net> wrote...
> > > > > Hicham BOUHMADI wrote:
> > > > >
> > > > > > There is many features in the C++ that are not exploited
> > enough...
> > > > > > one of those feature are the overloading of the ','
operator.
> > > > > >
> > > > > > Is there anyone who has a 'good' and 'usefull' example of
this
> > > > feature?
> > > > >
> > > > > Take a look at Blitz++
> > > > >
> > > > >     http://www.oonumerics.org/blitz/
> > > >
> > > > I did.  And I have questions.  Can you tell me how it is
possible
> > > > to use "list initialiser" in the form
> > > >
> > > >     Array<int,1> A(3);
> > > >     A = 1, 0, 1;
> > > >
> > > > when operator comma has LOWER precedence than assignment
operator
> > > > (and the precedence cannot be changed by overloading)?
> > > >
> > > > As far as my poor knowledge of C++ is concerned, the statement
> > > > should be interpreted as "(A = 1), NOP, NOP;" which is "A = 1;".
> > > >
> > > > Please give me a hand here.
> > >
> > > C'mon Victor,
> > >
> > > A = 1 sets the first element of array A to 1
> > > --> and returns an expression object <--
> > > so that we now have
> > >
> > >     expression(A = 1), 0, 1;
> > >
> > > expression(A = 1), 0 sets the second element of A to 0
> > > --> and returns another expression object <--
> > > so that we now have
> > >
> > >     expression(expression(A = 1), 0), 1;
> > >
> > > which sets the third element of A to 1
> > > --> and returns yet another expression object <--
> > > which might, I suppose, be cast into a reference to array A.
> >
> > I read the source, I understood what it did.  THAT was not the
> > problem.  The problem is to convince me that what's going on is
> > right.
> >
> > > The Blitz++ developers implement all this
> > > with (inline) expressions which the compiler optimizes away
> > > so that the full expression is equivalent to
> > >
> > >     A[0] = 1; A[1] = 0; A[2] = 1;
> > >
> > > Is this useful?  I don't know.  I'll let you judge.
> > > To me, at least, it does appear to make the code more readable.
> >
> > To me it doesn't.  Namely because the assignment has the higher
> > precedence.
> >
>
> If assignment had lower precedence it would not work.

Of course it wouldn't.

>
> It's an idiom.  You don't expect to read idioms literally.

No, but you would expect to understand the '+' as "addition" for any
type defining it, wouldn't you?  Or unary '-' as negation of some
kind...

There are predefined meanings to language constructs, and those are
dictated partially by operator precedence.  Would you expect to read
a < b as assigning some part of the value b to the respective part of a?
Or would you expect a << b to mean "much less than" for some type?  I
wouldn't.  Maybe I am just too thickheaded...  Well, that's why I am
explaining this to you now.

> [...]
>
> >
> > The expression
> >     <variable> = <value>, <value>, <value>
> > does NOT mean
> >     <variable> := SOMECOMBINATIONOF(<value>,<value>,<value>)
> > to me.
> >
> > The LANGUAGE, while allowing for such strange constructs, should
> > NOT be used in such way, IMHO.
> >
> > I can understand
> >     A(1, 0, 1); // some kind of freaky function call (through '...')
> > but not what they did.  However KEWL they might consider it.
>
> Do you have the same difficulty with:
>
>     cout << 1 << 0 << 1;
>
> ... It's the same kind of idiom.

Not really.  The above is the same as

    whatever + 1 + 3 + 123;

Left-to-right associativity, no precedence tricks.

Imagine that with some kind of overloading this

    whatever -> a == b == c ;

means "distribute whatever between a, b, and c evenly".  Do you
expect that to happen just by reading that "idiom"?  And I am fairly
sure it can be done since operator -> has higher precedence than
operator ==.

Should it be done?  I don't think so.  And if I see something like
that, I wouldn't be able to understand it right away.

Victor
--
Please remove capital A's from my address when replying by mail



---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: llewelly.@@edevnull.dot.com
Date: 2000/08/18
Raw View
Michiel Salters <salters@lucent.com> writes:

> [ Snipped quite a lot. MS. ]
>
> "llewelly."@@edevnull.dot.com wrote:
>
> > David R Tribble <david@tribble.com> writes:
>
> > >    cout << x;       // Shift x to the output?
> > >    cout.print(x);   // Is this really less readable?
>
> > The principal problem with having an [io]stream::print() method is
> >   that C++ has no type safe variable argument functions; such a print
> >   method would have to take a fixed number of arguments, making stream
> >   i/o quite tedious and irritating.
>
> > Overloading a operator<<() is used as a kind of substitute. I do not
> >   think that << and >> are 'obvious' i/o operators, but I do think
> >   that their use in C++ streams is just about the best overall
> >   decision the language allows.
>
> The problem of no variable argument lists is as much a problem for
> ostream::print() as it is for ostream::operator<<(), that is, no
> problem at all. But I'd call it ostream::pr() to shorten it:
>
> cout.pr("The price is ").pr(5).pr(" dollar and
> ").pr(52).pr("Cents");

I did not think of that. It does look ugly, but when I first saw
  <iostream>'s use of operator<<(), I thought << was ugly too, but I
  have since come to like it.

>
> The problem with this syntax is that it's not simply extensible, you can't
> add ostream.pr(MyClass). This is a theoretical problem, though:

I think you mean 'an easily solved problem', not 'a theoretical
  problem' .

> ostream::pr(T) would just call user_defined_print(ostream&, T).
> The only problem would be that this might require partial specialization
> of member functions, I think, to make ostream::pr(int) a special
> case.

No - the library could  could just implement:

  ostream& user_defined_print(ostream&,int);
  ostream& user_defined_print(ostream&,double);

and so on, though now I think the name of user_defined_print() should
  be changed - perhaps to print() or type_specific_print(). But this
  is not really any better than partial specialization of the member
  function.

>
> Still, avoiding variable argument lists isn't the killer argument for
> operator<<() IMHO.
>
[snip]

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: kanze@gabi-soft.de
Date: 2000/08/19
Raw View
llewelly.@@edevnull.dot.com writes:

|>  > cout.pr("The price is ").pr(5).pr(" dollar and
|>  > ").pr(52).pr("Cents");

|>  I did not think of that. It does look ugly, but when I first saw
|>    <iostream>'s use of operator<<(), I thought << was ugly too, but I
|>    have since come to like it.

How about "cout.fmt( "The price is %4.2f dollars" ).with (5.52 )" ?

IMHO, its at least as good as the standard printf syntax, with perfect
(run-time, at least) type safety.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: kanze@gabi-soft.de
Date: 2000/08/19
Raw View
Michiel Salters <salters@lucent.com> writes:

|>  [ Snipped quite a lot. MS. ]

|>  The problem of no variable argument lists is as much a problem for
|>  ostream::print() as it is for ostream::operator<<(), that is, no
|>  problem at all. But I'd call it ostream::pr() to shorten it:

|>  cout.pr("The price is ").pr(5).pr(" dollar and ").pr(52).pr("Cents");

|>  The problem with this syntax is that it's not simply extensible, you
|>  can't add ostream.pr(MyClass).

Of course you can, now.  ostream::pr is a template member function for
which the user can (must?) provide a specialization.  (A potential
problem is that no user defined conversions would be considered.)

|>  This is a theoretical problem,
|>  though: ostream::pr(T) would just call user_defined_print(ostream&,
|>  T).

That's what I do in my Format class.  Except that the
"user_defined_print(ostream&,T)" is called "operator<<(ostream&,T)".
(Of course, I am working within the framework of an already designed
language, and trying to remain as compatible as possible.)

|>  The only problem would be that this might require partial
|>  specialization of member functions, I think, to make
|>  ostream::pr(int) a special case.

That's also the case with my Format class. It's necessary, IMHO, for two
reasons:

  - If the user specifies "%6.4f", and passes an int, you want to
    convert it to a float and convert accordingly.  (This often happens
    with literal constants: 0 instead of 0.0, for example.)

  - It allows support for things like "%*d", so that existing printf
    formatters can be used.  (For new code, overloading the template
    function to take additional parameters is probably a better
    solution; my Format class supports both.)

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Trevor L. Jackson, III" <fullmoon@aspi.net>
Date: 2000/08/19
Raw View
Victor Bazarov wrote:

> "Trevor L. Jackson, III" <fullmoon@aspi.net> wrote...
> > It's an idiom.  You don't expect to read idioms literally.
>
> No, but you would expect to understand the '+' as "addition" for any
> type defining it, wouldn't you?  Or unary '-' as negation of some
> kind...
>
> There are predefined meanings to language constructs, and those are
> dictated partially by operator precedence.  Would you expect to read
> a < b as assigning some part of the value b to the respective part of a?
> Or would you expect a << b to mean "much less than" for some type?  I
> wouldn't.

Funny you should mention this example.  I agree that operators should not
surprise their users.  But a couple months ago I asked exactly this question
regarding using <<, <<=, >> amd >>= as relational operators.  My concern was
the strength of the presumption on the part of the average reader.

Now if you came across code like this:

    void func( UDT const & value, UDT const & limit )    // You can assume a
UDT is a complex numeric type
    {
        if ( X <<= Y ) {
            /* Munch on X */
        }
    }

... would it really be that confusing?

>  Maybe I am just too thickheaded...  Well, that's why I am
> explaining this to you now.
>
> > [...]
> >
> > >
> > > The expression
> > >     <variable> = <value>, <value>, <value>
> > > does NOT mean
> > >     <variable> := SOMECOMBINATIONOF(<value>,<value>,<value>)
> > > to me.
> > >
> > > The LANGUAGE, while allowing for such strange constructs, should
> > > NOT be used in such way, IMHO.
> > >
> > > I can understand
> > >     A(1, 0, 1); // some kind of freaky function call (through '...')
> > > but not what they did.  However KEWL they might consider it.
> >
> > Do you have the same difficulty with:
> >
> >     cout << 1 << 0 << 1;
> >
> > ... It's the same kind of idiom.
>
> Not really.  The above is the same as
>
>     whatever + 1 + 3 + 123;
>
> Left-to-right associativity, no precedence tricks.
>
> Imagine that with some kind of overloading this
>
>     whatever -> a == b == c ;
>
> means "distribute whatever between a, b, and c evenly".  Do you
> expect that to happen just by reading that "idiom"?  And I am fairly
> sure it can be done since operator -> has higher precedence than
> operator ==.
>
> Should it be done?  I don't think so.  And if I see something like
> that, I wouldn't be able to understand it right away.

Agreed.  But the context, which is typically limited to initialization, is
going to give a reasonable hint to the reader.  I suppose that I prefer the
first of these two alternatives for reasons of readability:

    array_t A = 1, 2, 3, 4, 5;
    array_t A, 1, 2, 3, 4, 5;

... which brings up another alternative: overloading the assignment operator
to perform incremental initialization.  Would you find

    array_t A = 1 = 2 = 3 = 4 = 5;

... to be as confusing?  To me the sequence looks less like a list of values
that the comma delimited init above.

<rant>
The issue of array init interests me because I'd like to see partial array
initialization deprecated.  IMHO under initialization (fewer initializers than

elements) is an error just as over initialization is an error.  The only
sensible mechanism I've found is to leave array sizes undefined (which is an
efficiency hit) so that code using the array can assert that the actual size
taken from the init list matches the desired size.

But this fails for multi-dimensioned arrays.

If I could be sure that the compiler would complain about under init I'd be
free to declare the desired array sizes without becoming vulnerable to init
list maintenance leaving some elements uninitialized.
</rant>

Redefining the comma operator is extremely useful in avoiding this situation
because one can achieve initialization replication (filling multiple elements
from a single initializer) by overloading the comma operator.  The version
taking a simple type only fills one element.  The version taking a
pair<init,count> fills (count) elements.  When count is negative it fills "the

rest", or in strange cases all but the last abs(count) elements.

I'd like to use a similar mechanism for array allocation initialization, but
am not satisfied that it can be done cleanly in all cases.


---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: kanze@gabi-soft.de
Date: 2000/08/19
Raw View
David R Tribble <david@tribble.com> writes:

|>  In the July 2000 issue of "The Java Report", in an interview with
|>  James Gosling, Dennis Ritchie, and Bjarne Stroustrup, Gosling
|>  describes the reasons he didn't add operator overloading to Java:

It's interesting to note that Gosling is proposing adding operator
overloading to Java.  Precisely because of the impossibility for a user
to reasonably define a type like complex otherwise.  (Give it time: Java
is well on the road to becoming as complex as C++:-).)

    [...]
|>     Then there's a community of about 10% that have actually used
|>     operator overloading appropriately and who really care about it,
|>     and for whom it's actually really important; this is almost
|>     exclusively people who do numerical work,

Not quite.  Any accountant oriented commercial program needs decimal
arithmetic, and calculating the amortissement (is that the correct
English word?) of a loan without arithmetic operations leads to some
very untransparent expressions.  Another use would be typed currency, in
which you can add Euros to DM and get a result which can be read as
either Euros or DM -- this would be really useful to us at present:-).

    [...]
|>  The Blitz++ library is an example of the numerical folk who can
|>  use operator overloading to their advantage.  But outside the domain
|>  of numerical applications, I personally find operator overloading
|>  to be more confusing than using regular functions.

I regularly overload operator=3D, for example, for any number of
non-numeric types:-).

Seriously, I use operator overloading for three things in C++ (in
addition to assignment): numeric types, smart pointers (but not
iterators), and comparison.  (Actually, instead of numeric types, I
should say mathematic types -- I overload operators (|,&,~) in my set
types as well.)

|>     cout << x;       // Shift x to the output?
|>     cout.print(x);   // Is this really less readable?

|>     cin >> x;        // Shift input into x; or is it x << cin?
|>     cin.scan(&x);    // Does this hurt?

Given the relative frequency of the operations, I think it more accurate
to say that in C++, >> and << are the IO operators, and that they are
anomalously overloaded for shifting.

Coming from a C background, however, in modern C++, I would probably
want something like:

    cout( formatString ).with( arg1 ).with( arg2 ) ;

The problem is, this requires template member functions and a precise
rule about the lifetime of temporaries to work correctly.  Neither were
available when the first iostream saw the day.  (Note that this can be
made neatly thread-safe without a user defined mutex as well.  The
operator()(string) on ostream returns a temporary object which collects
and formats the data; its destructor triggers the actual output.)

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos Reis <gdr@merlin.codesourcery.com>
Date: 2000/08/19
Raw View
kanze@gabi-soft.de writes:

| Michiel Salters <salters@lucent.com> writes:
|
| |>  [ Snipped quite a lot. MS. ]
|
| |>  The problem of no variable argument lists is as much a problem for
| |>  ostream::print() as it is for ostream::operator<<(), that is, no
| |>  problem at all. But I'd call it ostream::pr() to shorten it:
|
| |>  cout.pr("The price is ").pr(5).pr(" dollar and ").pr(52).pr("Cents");
|
| |>  The problem with this syntax is that it's not simply extensible, you
| |>  can't add ostream.pr(MyClass).
|
| Of course you can, now.  ostream::pr is a template member function for
| which the user can (must?) provide a specialization.  (A potential
| problem is that no user defined conversions would be considered.)

At a first glance, I think that approach isn't very appealing: if the
specialization is missing then the primary template will be selected;
at best one gets a link-time error instead of compile-time error.  Of
course, that problem is easily worked around with:

| |>  This is a theoretical problem,
| |>  though: ostream::pr(T) would just call user_defined_print(ostream&,
| |>  T).
|
| That's what I do in my Format class.  Except that the
| "user_defined_print(ostream&,T)" is called "operator<<(ostream&,T)".

:-)

--
Gabriel Dos Reis, gdr@codesourcery.com
CodeSourcery, LLC  http://www.codesourcery.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/08/19
Raw View
In article <399E0C97.BC5E564B@aspi.net>, Trevor L. Jackson, III
<fullmoon@aspi.net> writes
>If I could be sure that the compiler would complain about under init I'd be
>free to declare the desired array sizes without becoming vulnerable to init
>list maintenance leaving some elements uninitialized.

But they aren't, if an array has insufficient initialisers though at
least one has been provided the extras are zero initialised. I would
hate it if it were otherwise. To my mind the current rule is exactly
right.

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

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Michiel Salters <salters@lucent.com>
Date: 2000/08/21
Raw View
"llewelly."@@edevnull.dot.com wrote:
>
> Michiel Salters <salters@lucent.com> writes:
>
> > [ Snipped quite a lot. MS. ]

[ About std::ostream::pr(T to_be_printed ]

> > The problem with this syntax is that it's not simply extensible, you can't
> > add ostream.pr(MyClass). This is a theoretical problem, though:

> > ostream::pr(T) would just call user_defined_print(ostream&, T).
> > The only problem would be that this might require partial specialization
> > of member functions, I think, to make ostream::pr(int) a special
> > case.

> No - the library could  could just implement:

>   ostream& user_defined_print(ostream&,int);
>   ostream& user_defined_print(ostream&,double);

> and so on, though now I think the name of user_defined_print() should
>   be changed - perhaps to print() or type_specific_print(). But this
>   is not really any better than partial specialization of the member
>   function.

Well, I thought of that, but I couldn't come up with a namespace to put them in.
The problem I saw is that overloading is done on a set of functions from
essentially one namespace, std::. The library would define
std::user_defined_print(ostream&,int); and
::user_defined_print(ostream, MyType) would never be selected. Another solution
would be

template <typename T> std::user_defined_print(ostream, T) {
 ::user_defined_print(ostream, T);
}

to forward (again) to another namespace.

But I think, were this solution chosen, adding extra overloads to
std:: would be common practice.

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://reality.sgi.com/austern_mti/std-c++/faq.html              ]