为什么结构化绑定只适用于自动

Why structured bindings only work with auto

Structured bindings 已在 c++17 中引入。它们提供了声明从元组或结构初始化的多个变量的能力。

此代码使用 c++17 编译器编译。

#include <iostream>
#include <tuple>

int main() {
    auto tuple = std::make_tuple(1.0, 1);

    auto [ d, i ] = tuple;

    std::cout << "d=" << d << " i=" << i <<  '\n';

    return 0;
}

如果我不使用 auto 声明变量,我会得到错误

错误:预期的 lambda 表达式正文 [d2 , i2] = 元组;

#include <iostream>
#include <tuple>

int main() {
    auto tuple = std::make_tuple(1.0, 2);

    double d2;
    int i2;

    [d2 , i2] = tuple;

    return 0;
}

我使用了 clang version 4.0.0 和编译选项 -std=c++1z

我可以将现有变量分配给结构化绑定吗?我需要使用 auto 吗?

您收到的错误消息很好地说明了为什么只允许使用 auto:没有歧义会使语法 更加 上下文相关。

表达式开头的一对方括号表示 lambda。您要求的是标准指定 sometimes [d2 , i2] 是按值捕获 d2i2 的 lambda 的开头,并且在其他时间,这是一个拆包作业。一切都基于它后面的内容。

将它添加到语言中是不值得的。特别是,由于 ,您已经 std::tie 可以用元组做您想做的事情。

不仅如此,std::tie 允许您忽略一些解压缩的值,这是结构化绑定尚不支持的。所以这一切都归结为具有更有限形式的语法糖,来做一些标准库已经用元组做的事情。


哦,如果您不满 std::tie 仅适用于元组,您可以自己扩展它以适用于任何 POD。看看这个 magic_get implementation。可以将相同的想法应用于 constexpr 将 POD 转换为可以提供给 std::tie 的引用元组。像这样:

std::tie(d2, i2) = magic_unpack(/*some POD that isn't a tuple*/);

此外,您还可以使用 std::tie() 将元组解包为各个组件。如

#include <iostream>
#include <tuple>

int main() {
    auto tuple = std::make_tuple(1.0, 1);
    double d2;
    int i2;
    std::tie(d2, i2) = tuple;

    std::cout << "d2=" << d2 << " i2=" << i2 <<  '\n';

    return 0;
}