Topic: Something about ?: and iostreams


Author: dhruvbird@gmx.net ("Dhruv")
Date: Mon, 8 Sep 2003 08:31:54 +0000 (UTC)
Raw View
On Thu, 04 Sep 2003 19:02:22 +0000, Ben Hutchings wrote:

> In article <pan.2003.09.03.13.49.38.744054@gmx.net>, "Dhruv" wrote:
>> I wanrted to know if it is requited by the standard for the ?: operator to
>> return the same value or related values, or nothing in particular is said
>> about the return values if the expression before the ? evaluates to true
>> or false.
>
> I am guessing that you mean type instead of value.
Yes, Sorry about that......

> The second and
> third sub-expressions in a conditional expression need not have the
> same type, but the conditional expression as a whole always yields
> the same type, applying conversions as necessary.  The conversion
> rules are complex and can be found in section 5.16.
>
>> So, is something like this valid:?
>> bool show_str = true;
>> cout<<(show_str?"hello":23)<<endl;
>
> This is invalid.
>
>> Or is this valid:?
>> struct B {};
>> struct A:public B {};
>>
>> //Assume I have overloaded operator<< for both A and B.
>> bool Show_A = true;
>> cout<<(Show_A?A():B())<<endl;
>
> This is valid and always results in calling B::operator<<.  If Show_A is
> true then a temporary instance of A is constructed and then converted to
> B.
>
>> I just wrote this code the other day, and when it started giving wierd
>> output, I realized that iostreams are now templated, so argument deduction
>> would be impossible in this case. So, it it explicitly required by the
>> standard for this to be invalid?
>
> I don't think the use of the conditional operator has any special
> interaction with argument deduction.

Ok, since returning values of 2 different types based on the condition
(1st argument) to ?: operator is illegal, this does not come into
picture. However, since you have mentioned it, I'd like to know how
exactly argument deduction happens in case of the ?: operator, because if
you have something like cout<<2; OR: cout<<5.75; then, the compiler, can
see that you have called the int and float specialization respectively,
but for ?: how does it know?

Regards,
-Dhruv.





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





Author: Ken@Alverson.net (Ken Alverson)
Date: Mon, 8 Sep 2003 17:16:14 +0000 (UTC)
Raw View
""Dhruv"" <dhruvbird@gmx.net> wrote in message
news:pan.2003.09.05.18.44.27.223921@gmx.net...
>
> Ok, since returning values of 2 different types based on the condition
> (1st argument) to ?: operator is illegal, this does not come into
> picture. However, since you have mentioned it, I'd like to know how
> exactly argument deduction happens in case of the ?: operator, because if
> you have something like cout<<2; OR: cout<<5.75; then, the compiler, can
> see that you have called the int and float specialization respectively,
> but for ?: how does it know?

The expression (bool_var ? 2 : 5.75) has only one type which is determined at
compile time, not runtime.  The common type here is double (both values can be
converted to double without losing information), so the entire expression has
a type of double.

No matter what the value of bool_var, any code using that expression will see
the result as a double, even if the 2 is chosen.

Ken


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





Author: Michiel.Salters@cmg.nl (Michiel Salters)
Date: Tue, 9 Sep 2003 01:35:26 +0000 (UTC)
Raw View
dhruvbird@gmx.net ("Dhruv") wrote in message news:<pan.2003.09.05.18.44.27.223921@gmx.net>...
> On Thu, 04 Sep 2003 19:02:22 +0000, Ben Hutchings wrote:

> Ok, since returning values of 2 different types based on the condition
> (1st argument) to ?: operator is illegal, this does not come into
> picture. However, since you have mentioned it, I'd like to know how
> exactly argument deduction happens in case of the ?: operator, because if
> you have something like cout<<2; OR: cout<<5.75; then, the compiler, can
> see that you have called the int and float specialization respectively,
> but for ?: how does it know?

Argument deduction is pretty simple. It's the same as with any other
expression. First, the typeof the expression is determined. For ?: that's
done by 5.16. Once the (single, unique, compile-time fixed) type is known
that type is used to choose/instantiate an overload. E.g. once it's known
that c?foo():bar() returns a T, std::cout << c?foo():bar() selects the
operator<< for Ts. The working of operator?: is not influenced by the
larger expression it belongs to.

Regards,
--
Michiel Salters

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





Author: kuyper@wizard.net (James Kuyper)
Date: Tue, 9 Sep 2003 11:37:35 +0000 (UTC)
Raw View
dhruvbird@gmx.net ("Dhruv") wrote in message news:<pan.2003.09.05.18.44.27.223921@gmx.net>...
...
> picture. However, since you have mentioned it, I'd like to know how
> exactly argument deduction happens in case of the ?: operator, because if
> you have something like cout<<2; OR: cout<<5.75; then, the compiler, can
> see that you have called the int and float specialization respectively,
> but for ?: how does it know?

It knows the same way that it knows for any other expression. I uses
the types of the operands for operater<<(). That means it has to
figure out what the type of the ?: expression. For

        cout << (a ? b : c);

the type of the ?: expression is the common type that both b and c can
be converted to, according to the rather complex rules given in
section 5.15.

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





Author: dhruvbird@gmx.net ("Dhruv")
Date: Wed, 3 Sep 2003 16:46:00 +0000 (UTC)
Raw View
I wanrted to know if it is requited by the standard for the ?: operator to
return the same value or related values, or nothing in particular is said
about the return values if the expression before the ? evaluates to true
or false.

So, is something like this valid:?
bool show_str = true;
cout<<(show_str?"hello":23)<<endl;

Or is this valid:?
struct B {};
struct A:public B {};

//Assume I have overloaded operator<< for both A and B.
bool Show_A = true;
cout<<(Show_A?A():B())<<endl;

I just wrote this code the other day, and when it started giving wierd
output, I realized that iostreams are now templated, so argument deduction
would be impossible in this case. So, it it explicitly required by the
standard for this to be invalid?


-Dhruv.











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





Author: do-not-spam-benh@bwsint.com (Ben Hutchings)
Date: Thu, 4 Sep 2003 19:02:22 +0000 (UTC)
Raw View
In article <pan.2003.09.03.13.49.38.744054@gmx.net>, "Dhruv" wrote:
> I wanrted to know if it is requited by the standard for the ?: operator to
> return the same value or related values, or nothing in particular is said
> about the return values if the expression before the ? evaluates to true
> or false.

I am guessing that you mean type instead of value.  The second and
third sub-expressions in a conditional expression need not have the
same type, but the conditional expression as a whole always yields
the same type, applying conversions as necessary.  The conversion
rules are complex and can be found in section 5.16.

> So, is something like this valid:?
> bool show_str = true;
> cout<<(show_str?"hello":23)<<endl;

This is invalid.

> Or is this valid:?
> struct B {};
> struct A:public B {};
>
> //Assume I have overloaded operator<< for both A and B.
> bool Show_A = true;
> cout<<(Show_A?A():B())<<endl;

This is valid and always results in calling B::operator<<.  If Show_A is
true then a temporary instance of A is constructed and then converted to
B.

> I just wrote this code the other day, and when it started giving wierd
> output, I realized that iostreams are now templated, so argument deduction
> would be impossible in this case. So, it it explicitly required by the
> standard for this to be invalid?

I don't think the use of the conditional operator has any special
interaction with argument deduction.

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





Author: rmaddox@isicns.com (Randy Maddox)
Date: Fri, 5 Sep 2003 19:50:28 +0000 (UTC)
Raw View
dhruvbird@gmx.net ("Dhruv") wrote in message news:<pan.2003.09.03.13.49.38.744054@gmx.net>...
> I wanrted to know if it is requited by the standard for the ?: operator to
> return the same value or related values, or nothing in particular is said
> about the return values if the expression before the ? evaluates to true
> or false.

See 5.16 for description of the conditional operator.

>
> So, is something like this valid:?
> bool show_str = true;
> cout<<(show_str?"hello":23)<<endl;

I believe this should be a compile time error since the types on
either side of the : are not convertible to each other.

>
> Or is this valid:?
> struct B {};
> struct A:public B {};
>
> //Assume I have overloaded operator<< for both A and B.
> bool Show_A = true;
> cout<<(Show_A?A():B())<<endl;

I believe this should be OK, but if Show_A is true then, given what
you show here, you would get a B object converted from the default
constructed A object.

>
> I just wrote this code the other day, and when it started giving wierd
> output, I realized that iostreams are now templated, so argument deduction
> would be impossible in this case. So, it it explicitly required by the
> standard for this to be invalid?
>
>
> -Dhruv.
>

I could well be wrong on either or both counts as I found 5.16 very
difficult to read and understand.  :-)  The bottom line seems to be
that the types of the expressions on each side of the : must generally
be convertible to a single type, which makes sense because the
compiler needs to know the type of the result of the ?: operator.

Randy.

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





Author: bop2@telia.com ("Bo Persson")
Date: Fri, 5 Sep 2003 19:50:54 +0000 (UTC)
Raw View
""Dhruv"" <dhruvbird@gmx.net> skrev i meddelandet
news:pan.2003.09.03.13.49.38.744054@gmx.net...
> I wanrted to know if it is requited by the standard for the ?:
operator to
> return the same value or related values, or nothing in particular is
said

There is a lot said about the conditional operator (about a page and a
half). Basically the two expressions after the ? should be the same
type, or one convertible to the other. Otherwise the program is
ill-formed.

> about the return values if the expression before the ? evaluates to
true
> or false.
>
> So, is something like this valid:?
> bool show_str = true;
> cout<<(show_str?"hello":23)<<endl;

You definitely have a problem here if the overload resolution cannot
tell if you pass a string or an int.

In this particular case, this might be complicated by the constant
condition.

>
> Or is this valid:?
> struct B {};
> struct A:public B {};
>
> //Assume I have overloaded operator<< for both A and B.
> bool Show_A = true;
> cout<<(Show_A?A():B())<<endl;

Here I believe the values are converted to the common type B.


Bo Persson

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





Author: STOPcwvcaSPAM@hotmail.com (Colin)
Date: Fri, 5 Sep 2003 19:51:12 +0000 (UTC)
Raw View
dhruvbird@gmx.net ("Dhruv") writes:

> I wanrted to know if it is requited by the standard for the ?:
> operator to return the same value or related values, or nothing in
> particular is said about the return values if the expression before
> the ? evaluates to true or false.

The conditional operator must return the same type for both the true
and false cases.

> So, is something like this valid:?  bool show_str = true;
> cout<<(show_str?"hello":23)<<endl;

No. "hello" and 23 must be of the same type to succeed.

> Or is this valid:?  struct B {}; struct A:public B {};

No. There's no first operand before the "?".  However, if the "?" is
not part of the code then yes, it is legal.  The only difference
between classes and structs is that the protection level of classes
are private by default while the protection level of structs are
public by default.

> //Assume I have overloaded operator<< for both A and B.  bool Show_A =
> true; cout<<(Show_A?A():B())<<endl;

If A and B are functions then they must return the same type.  If A
and B are classes then this won't work.

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





Author: jackklein@spamcop.net (Jack Klein)
Date: Mon, 8 Sep 2003 08:27:35 +0000 (UTC)
Raw View
On Wed, 3 Sep 2003 16:46:00 +0000 (UTC), dhruvbird@gmx.net ("Dhruv")
wrote in comp.std.c++:

> I wanrted to know if it is requited by the standard for the ?: operator to
> return the same value or related values, or nothing in particular is said
> about the return values if the expression before the ? evaluates to true
> or false.
>
> So, is something like this valid:?
> bool show_str = true;
> cout<<(show_str?"hello":23)<<endl;
>
> Or is this valid:?
> struct B {};
> struct A:public B {};
>
> //Assume I have overloaded operator<< for both A and B.
> bool Show_A = true;
> cout<<(Show_A?A():B())<<endl;
>
> I just wrote this code the other day, and when it started giving wierd
> output, I realized that iostreams are now templated, so argument deduction
> would be impossible in this case. So, it it explicitly required by the
> standard for this to be invalid?
>
>
> -Dhruv.

According to my reading 5.6 of the C++ standard, your program is
ill-formed.  That is because there is no single type that both
expressions can be converted to.  If a program is ill-formed, the
compiler must issue a diagnostic.  Did yours?  If a compiler produces
an executable from an ill-formed program, and that executable is run,
the behavior is undefined.

In your second example, it appears that 5.6 specifically allows the
use of base and derived classes, so this example is not ill-formed,
but since the result is an lvalue (an actual object), the derived
class would get sliced its base case component because the value
yielded by the expression would be a base class object.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

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





Author: kanze@gabi-soft.fr
Date: Mon, 8 Sep 2003 08:29:42 +0000 (UTC)
Raw View
dhruvbird@gmx.net ("Dhruv") wrote in message
news:<pan.2003.09.03.13.49.38.744054@gmx.net>...

> I wanrted to know if it is requited by the standard for the ?:
> operator to return the same value or related values, or nothing in
> particular is said about the return values if the expression before
> the ? evaluates to true or false.

> So, is something like this valid:?
> bool show_str = true;
> cout<<(show_str?"hello":23)<<endl;

What is (or should be) the static type of the expression:
    show_str ? "hello" : 23
?

This has nothing to do with iostreams. Every legal expression must have
a fixed static type.  C++ does static type checking.  And the type
cannot (with very few exceptions) depend on context.

> Or is this valid:?
> struct B {};
> struct A:public B {};

> //Assume I have overloaded operator<< for both A and B.
> bool Show_A = true;
> cout<<(Show_A?A():B())<<endl;


No problem here.     5.16/3 says that the type of the ?: expression is A.

> I just wrote this code the other day, and when it started giving wierd
> output, I realized that iostreams are now templated, so argument
> deduction would be impossible in this case.

There is no problem with argument deduction in either case.  A ?:, like
any other expression, has a type, and that type is used for argument
deduction.

If it is giving weird output, it is probably due to something in the
operator<< for A.

> So, it it explicitly required by the standard for this to be invalid?

No.  It is explicitly required that it work.

--
James Kanze           GABI Software        mailto:kanze@gabi-soft.fr
Conseils en informatique orient   e objet/     http://www.gabi-soft.fr
                    Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

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





Author: kuyper@wizard.net (James Kuyper)
Date: Mon, 8 Sep 2003 08:30:15 +0000 (UTC)
Raw View
dhruvbird@gmx.net ("Dhruv") wrote in message news:<pan.2003.09.03.13.49.38.744054@gmx.net>...
> I wanrted to know if it is requited by the standard for the ?: operator to
> return the same value or related values, or nothing in particular is said
> about the return values if the expression before the ? evaluates to true
> or false.

I think, given your example below, that you're really trying to ask a
different question. Would this be a correct restatement?:

"I wanted to know if it is required by the standard for the second and
third arguments of the ?: operator to be expressions with the same
type, or related types, or is nothing in particular said about that?"

If that's what you're really asking, then the answer is that the value
returned by the ?: must have the same type, no matter which value the
first operand has. Therefore, both of the second two operands must be
converted to a single common type. If there is an unambiguous single
type they can both be imnplicitly converted to, the expression is
well-formed. If there is no such type, or if the common type is
ambiguous, then it isn't. The actual rules are much more complicated
than that, but those are the basic principles.

> So, is something like this valid:?
> bool show_str = true;
> cout<<(show_str?"hello":23)<<endl;

In this case, there's no common type, so the expression is ill-formed.

> Or is this valid:?
> struct B {};
> struct A:public B {};
>
> //Assume I have overloaded operator<< for both A and B.
> bool Show_A = true;
> cout<<(Show_A?A():B())<<endl;

In this case, A() can be implicitly converted to a B. If there is an
applicable conversion constructor or type cast overload, then B() can
also be converted to an A, the common type is ambiguous, and the
expression is ill-formed. However, if there are no such user-defined
conversions, the expression is legal, and equivalent to:

cout << (Show_A ? B(A()) : B() ) << endl;

In the unlikely event that you A() to be sliced to a B, then the code
is fine.

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





Author: petebecker@acm.org (Pete Becker)
Date: Mon, 8 Sep 2003 08:30:27 +0000 (UTC)
Raw View
Ben Hutchings wrote:
>
> > So, is something like this valid:?
> > bool show_str = true;
> > cout<<(show_str?"hello":23)<<endl;
>
> This is invalid.
>

Just one little clarification to what Ben said: the problem has nothing
to do with streams. It's in the expression

 show_str ? "hello" : 23

which simply isn't valid.

--

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

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