为什么结构化绑定仅适用于auto

sch*_*312 8 c++ auto c++17 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;
}
Run Code Online (Sandbox Code Playgroud)

如果我没有声明变量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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Sto*_*ica 9

你得到的错误信息非常能说明为什么它只允许auto:缺乏歧义,这会使语法更依赖于语境.

表达式开头的一对方括号表示lambda.你要问的是标准指定有时 [d2 , i2]是一个lambda的开始,它捕获d2和i2按值,而在其他时候它是一个解包分配.一切都基于它的后续内容.

将它添加到语言中并不值得复杂.特别是,正如一些程序员老兄指出的那样,你必须std::tie用元组做你想做的事.

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


哦,如果你是std::tie只适用于元组的不满,你可以将它扩展为自己使用任何POD.看看这个magic_get实现.可以应用相同的想法constexpr将POD转换为可以馈送到的参考元组std::tie.像这样的东西:

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

  • 我认为这根本不是真的。如果未使用 auto,您可以在结构化绑定之前添加一个关键字,如下所示:“structural_binding [d2, i2] = tuple”。其他人可以想出一个看起来不错的语法,但是解析起来与“auto”的工作量是一样的。然后你可以这样做:`strucutured_binding [ bool d2, int i2]`。这就是我想要该功能的主要原因,因为您可以使用具有显式类型和不可默认构造的东西的结构化绑定。 (3认同)

msc*_*msc 5

此外,您还可以使用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;
}
Run Code Online (Sandbox Code Playgroud)