I wanted to be able to do multiple assignments in an if block and short-circuit if the first one fails. However, this does not compile and says, expected primary-expression before ‘auto’
#include <iostream>
#include <optional>
std::optional<int> foo()
{
return 0;
}
int main() {
if (auto a = foo() && auto b = foo())
{
std::cout << "a = " << *a << ", b = " << *b << std::endl;
}
}
The following works though and does what I want.
if (auto a = foo())
{
if (auto b = foo()) {
std::cout << "a = " << *a << ", b = " << *b << std::endl;
}
}
But is there a way for me to use the syntax in the first one? Using parenthesis to surround the expressions does not work.
Since C++17, you could write
if (decltype(foo()) a, b; (a = foo()) && (b = foo()))
{
std::cout << "a = " << *a << ", b = " << *b << std::endl;
}
But if you want to see the short circuit in action, you should change the condition:
#include <iostream>
#include <optional>
std::optional<int> foo()
{
std::cout << "foo called.\n";
return 1;
}
int main()
{
if (decltype(foo()) a, b; (a = foo()) or (b = foo()))
{
// For exposition only ^^
std::cout << "a = " << *a << ", b = " << *b << std::endl;
// Note that, now, this is UB ^^
}
}
Compare the output of this
foo called. a = 1, b = 0
Versus the former.
It has nothing to do with auto. Declarations cannot be part of an expression. You can either use an expression or a single declaration inside an if statement.
So even this will not compile:
#include <iostream>
int foo()
{
return 0;
}
int main()
{
if (int a = foo() && int b = foo())
{
std::cout << "a = " << a << ", b = " << b << std::endl;
}
return 0;
}
Edit: In C++17 you can have an initializer statement before the condition statement, like so: if (auto a = foo(), b = foo(); a && b). However that will not give you short circuiting.
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