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.