c ++:if块语法内部的多重赋值用于短路
c++: Multiple assignment inside if block syntax for short circuiting
我希望能够在一个 if 块中进行多项赋值,并在第一个失败时短路。但是,这不会编译并说,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;
}
}
下面的方法虽然有效,但可以满足我的要求。
if (auto a = foo())
{
if (auto b = foo()) {
std::cout << "a = " << *a << ", b = " << *b << std::endl;
}
}
但是有没有办法让我使用第一个中的语法?使用圆括号包围表达式不起作用。
从 C++17 开始,您可以编写
if (decltype(foo()) a, b; (a = foo()) && (b = foo()))
{
std::cout << "a = " << *a << ", b = " << *b << std::endl;
}
但是如果你想看到动作中的短路,你应该改变条件:
#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 ^^
}
}
比较this
的输出
foo called.
a = 1, b = 0
与 former.
与auto
无关。声明不能是表达式的一部分。您可以在 if 语句中使用表达式或单个声明。
所以即使这样也不会编译:
#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;
}
编辑: 在 C++17 中,您可以在条件语句之前有一个初始化语句,如下所示:if (auto a = foo(), b = foo(); a && b)
。然而,这不会让你短路。
我看到的唯一方法是重新表述(不在 if
条件内声明变量):
#include <iostream>
#include <optional>
std::optional<int> foo()
{
return 0;
}
int main() {
std::optional<int> a , b;
if ((a = foo()) && (b = foo()))
{
std::cout << "a = " << *a << ", b = " << *b << std::endl;
}
}
请查看工作示例here。
从 c++17 开始,您甚至可以像这样在 if
条件中进行变量声明:
if (std::optional<int> a , b; (a = foo()) && (b = foo()))
尽管在那种情况下无法使用 auto
。
另一个live demo.
我希望能够在一个 if 块中进行多项赋值,并在第一个失败时短路。但是,这不会编译并说,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;
}
}
下面的方法虽然有效,但可以满足我的要求。
if (auto a = foo())
{
if (auto b = foo()) {
std::cout << "a = " << *a << ", b = " << *b << std::endl;
}
}
但是有没有办法让我使用第一个中的语法?使用圆括号包围表达式不起作用。
从 C++17 开始,您可以编写
if (decltype(foo()) a, b; (a = foo()) && (b = foo()))
{
std::cout << "a = " << *a << ", b = " << *b << std::endl;
}
但是如果你想看到动作中的短路,你应该改变条件:
#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 ^^
}
}
比较this
的输出foo called. a = 1, b = 0
与 former.
与auto
无关。声明不能是表达式的一部分。您可以在 if 语句中使用表达式或单个声明。
所以即使这样也不会编译:
#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;
}
编辑: 在 C++17 中,您可以在条件语句之前有一个初始化语句,如下所示:if (auto a = foo(), b = foo(); a && b)
。然而,这不会让你短路。
我看到的唯一方法是重新表述(不在 if
条件内声明变量):
#include <iostream>
#include <optional>
std::optional<int> foo()
{
return 0;
}
int main() {
std::optional<int> a , b;
if ((a = foo()) && (b = foo()))
{
std::cout << "a = " << *a << ", b = " << *b << std::endl;
}
}
请查看工作示例here。
从 c++17 开始,您甚至可以像这样在 if
条件中进行变量声明:
if (std::optional<int> a , b; (a = foo()) && (b = foo()))
尽管在那种情况下无法使用 auto
。
另一个live demo.