Can a constructor call be evaluated to a boolean if the bool() operator is overloaded?
class A
{
public:
A() {};
operator bool() const { return true; }
}
main()
{
if (A a = A())
{
// do stuff
}
}
Is the above code valid, or do I need to implement main like:
int main(int argc, const char* argv[])
{
A a();
if (a)
{
// do stuff
}
}
This code is going to wind up all over the place in my code base, so less lines, increased legibility, and reduced scope are important, and would be improved by this.
Any ideas?
The code contains a few syntactic and semantic bugs. Let's fix them
class A
{
public:
A() {};
operator bool() { return true; }
};
int main()
{
if (A a = A())
{
// do stuff
}
}
You may choose to change the type in the conversion function to something else. As written, the boolean conversion will also succeed to convert to any integer type. Converting to void*
will limit conversion to only bool and void*
, which is a commonly used idiom. Yet another and better way is to convert to some private type, called safe bool idiom.
class A
{
private:
struct safe_bool { int true_; };
typedef int safe_bool::*safe_type;
public:
A() {};
operator safe_type() { return &safe_bool::true_; }
};
Back to syntax: If you have an else part, you may use the name of the declared variable, because it's still in scope. It's destroyed after all branches are processed successfully
if(A a = A())
{ ... }
else if(B b = a)
{ ... }
You may also use the same name as before, and the variable will shadow the other variables, but you may not declare the same name in the most outer block of any branch - it will conflict rather than hide with the other declaration.
if(int test = 0)
{ ... }
else
{ int test = 1; /* error! */ }
The technique to declare and initialize a variable is most often used together with dynamic_cast
though, but can be perfectly used together with a user defined type like above, too
if(Derived *derived = dynamic_cast<Derived*>(base)) {
// do stuff
}
Note that syntactically, you have to initialize the variable (using the = expression
form like for a default argument). The following is not valid
if(ifstream ifs("file.txt")) {
// invalid. Syntactic error
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With