18

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] = tuple;

#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吗?

4

2 回答 2

15

您收到的错误消息非常说明为什么它只允许使用auto: 缺乏歧义,这将使语法更加依赖上下文。

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

将其添加到语言中是不值得的。特别是,正如一些程序员老兄指出的那样,您已经必须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*/);
于 2017-10-16T07:12:38.383 回答
3

此外,您可以使用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;
}
于 2017-10-16T07:38:48.110 回答