Given
!=
==
&&
which are used within one conditional clause, how can I find out which one will be evaluated first ?
e.
if(c==a!=b&&c!=b)
//dosomething
Thank you
Printable View
Given
!=
==
&&
which are used within one conditional clause, how can I find out which one will be evaluated first ?
e.
if(c==a!=b&&c!=b)
//dosomething
Thank you
Operators:Precedence of operators : http://www.cplusplus.com/doc/tutorial/operators/
:D thank monarchy
Use parentheses to enforce the order so that no one else has to try to remember the precedence when they look at your code.
Just a warning: "which one will be evaluated first" has to do with order of evaluation, which is sometimes a consequence of the grouping of subexpressions (and thus precedence), but generally the rules of precedence are specified, whereas order of evaluation is generally unspecified.
Also, be ware of short-circuit:
the (non-overloaded) operator&& and operator|| will NOT evaluate the second parameter if the first is false or true respectively. This is because it is useless. (false && x is always false, true || x is always true).
This is a very know behavior that is not only useful, but relied on.
if p->is_valid was evaluated, but p was null, the consequences would be catastrophic.Code:int * p = 0;
...
if (p && p->is_valid())
...
Let me get this right ... that does not apply to overloaded && operators then.
Thinking about how it would be used, with two parameters (or 'this' and one parameter), the right hand parameter would have to be evaluated before the operator could be called.
I suppose you'd only ever overload it if you did not want the default && behaviour, but it still seems a shame that you cannot keep the 'lazy and' characteristics.
For smart pointers you could overload the boolean operator instead, but when would you ever want to overload && or || in real code ?
Then again INT could have been anything. :D
I highly recommend against the operator bool. If you were to implement it, it means your type could also be cast implicitly to int or double.
Instead, implement the "operator void const*" and "operator!". void* can be on be implicitly cast implicitly to bool. Since the compiler is only allowed 2 implicit casts before giving up, this make your type convertible to bool, and that is it. This make sure you don't have any weird behaviors.
std::iostream does it this way.
In real code, there is no reason to overload && or ||. Even if the overloaded version kept the short-circuit behavior, it is much more practical to allow your type to be evaluated as true or false, and use the default operator.
Not really: weird behaviour is still possible, though less likely.Quote:
Originally Posted by monarch_dodra
This is weird, to me:Quote:
Originally Posted by monarch_dodra
The current solution for this weirdness is to implement the safe bool idiom; in the next version of C++ we can simply implement an explicit conversion function to bool.Code:#include <iostream>
int main()
{
std::cout << std::cin;
}
All correct, but the problem with explicit conversion is that it is not implicit :)
This would fail to compile with safe conversion. I would say the only absolutely safe way to do it is to provide a "operator bool_proxy", where bool_proxy is a type that can't do anything but be (implicitly) cast to bool.Code:if (std::cin)
Kind of like null_ptr_t* I guess: It's not a pointer, but it can be converted to a pointer.
*As a matter of fact, null_ptr can be implemented as a template, so I don't see why you can't do the same thing with bool.
No. If you insist otherwise, then be prepared: a standard library implementation that conforms to what is expected to be the next version of the C++ standard will cause your code snippet to fail to compile ;)Quote:
Originally Posted by monarch_dodra
Just to be more specific ( and to see if I got it right :) ), in the next standard implicit boolean conversions are treated as direct initializations of the boolean target ( that is "bool b(t);" and not "bool b = t;" ). For this reason that code * would compile with an explicit bool conversion function (laserlight, correct me if I'm wrong :) ).
*: I mean the "if( std::cin )" snippet
Holy crap, you're right!
That's gonna break a lot of code!Code:27.5.4 Class template basic_ios [ios]
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_ios : public ios_base {
public:
// types:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
explicit operator bool() const;
bool operator!() const;
iostate rdstate() const;
void clear(iostate state = goodbit);
void setstate(iostate state);
bool good() const;
bool eof() const;
bool fail() const;
bool bad() const;
Guess I'll just use
Much faster than typing static_cast<bool> ;)Code:while (!!std::cin)
From the Wikipedia page of C++0x:
So it's not that bad.Quote:
In C++0x, the explicit keyword can now be applied to conversion operators. As with constructors, it prevents the use of those conversion functions in implicit conversions. However, language contexts that specifically require a boolean value (the conditions of if-statements and loops, as well as operands to the logical operators) count as explicit conversions and can thus use a bool conversion operator.
And as far as I'm aware, the C++0x committee goes out of its way not to break existing code.
but what about (bool) ? and !! isn't that informative on what that actually means :)Quote:
Originally Posted by monarch_dodra
Err... I was being serious. As far as I know, explicit conversion functions to bool are specifically designed to replace the safe bool idiom and other existing methods to try and convert to bool without allowing unexpected behaviour, i.e., it is the case that it is not going to break existing code.Quote:
Originally Posted by monarch_dodra
Consider:Quote:
Originally Posted by monarch_dodra
Quote:
Originally Posted by C++ Standard Working Draft 2010-08-21 Clause 4 Paragraph 3 (part)
Quote:
Originally Posted by C++ Standard Working Draft 2010-08-21 Clause 5.14 Paragraph 1 (part)
well, bool is a C-cast. I stay clear away from those. !! is just as informative as static_cast<bool> if you're used to them. As always, it is just a language construct you have seen before and understand, or it isn't and you have to think about it. Were I work, we have objects that can't be cast to bool, but have operator!. We use "if (!!a)" all the time, and when we see "!!" we know exactly what it means. And it's safe.
I was acknowledging what was being said to me. Maybe "I see" can be interpreted as sarcasm in some context, but this was not the case here.
Thank you very much. You have taught me two very interesting things today. Pardon me if my surprised looked like mockery. It wasn't.
Yes, static_cast is preferable, but when it comes to the primitive types, the c-cast works fine. I only worry when it comes to polymorphism and class pointers in general.Quote:
Originally Posted by monarch_dodra
I would hate to write this all over my code
vsCode:int I = 10;
int I2 = 3;
float F = static_cast<float>( I ) / I2;
Code:int I = 10;
int I2 = 3;
float F = (float) I / I2;