有没有办法指定结构化绑定的哪些部分应该是引用?

问题描述 投票:0回答:1

我有一个 POD 结构

struct query{
 int l, r, ans;
};

我想写一个基于范围的循环:

std::vector<query> q;

for (auto [l, r, &ans]: q) {
    // perhaps I want to modify l and r here, but I want to store the result in ans.
    // Furthermore, I will reuse Q with the same **original** l and r later, but
    // don't want to create temporary variables to achieve the same effect 
}

对于这个“问题”有许多明显的快速解决方案,包括为 ans 创建一个外部数组,制作临时数组,或者可能与 std::tie: 一起破解一些东西:

        int ty, l, r, x;
        int& ans = elem.ans; 
        std::tie(ty, l, r, x, std::ignore) = std::tie(elem.ty, elem.l, elem.r, elem.x, elem.ans);

是的,我对两行额外的代码感到悲伤。但是我想知道我可以滥用 c++17 和 c++20 功能来编写更清晰、更短的代码。

郑重声明,代码片段 1 无法编译;根据 cppreference,它必须是一个标识符,没有任何引用限定符。所以我认为结构化绑定在这里不起作用。但也许一些我不知道的 std::tie 魔法或其他语言功能可以解决我的问题?任何想法表示赞赏。

c++ c++17 c++20
1个回答
0
投票

嗯,您始终可以创建到另一个元组的结构化绑定...

query q {1, 2, 0};
auto [l, r, ans] = std::make_tuple(q.l, q.r, std::ref(q.ans));
ans = l + r;
std::cout << q.ans; // 3

std::make_tuple
将创建一个元组,其中包含从每个相应参数复制/移动的值,除非该参数是
std::reference_wrapper
。在这种情况下,元组将引用引用包装器引用的任何内容。
std::reference_wrapper
在标准库中的很多地方使用来明确要求引用语义。

现在,如果您愿意将向量传递给对每个成员执行上述操作的变换视图,您就可以得到您想要的

auto make_binding = std::views::transform([](query const& o) { return std::make_tuple(o.l, o.r, std::ref(o.ans)); });
for (auto [l, r, ans]: q | make_binding) {
    
}
© www.soinside.com 2019 - 2024. All rights reserved.