为什么我不能将std::map的条目解包成引用?

4
我注意到从std::map中解包键和值不会给我引用。我假设std::map中的单个条目存储为const键值对。
可以使用以下方式工作:
  • std::map中的pair手动转换为引用。
  • 将使用std::make_pair创建的pair解包为引用。
  • std::views::values的结果中获取引用。
以下方式无法工作:
  • 直接将map条目在for循环中解包为引用
  • 将从迭代器获取的map条目解包为引用
为什么以上两种方式不起作用?下面是一个示例源代码和IDE推导出的类型。编译器插入同样的错误消息。
#include <map>
#include <type_traits>
#include <ranges>

int main() {
    std::map<int, int> data;

    for (const auto& kv : data) {
        auto& v = kv.second;
        auto& [a, b] = kv;
        static_assert(std::is_reference_v<decltype(v)>);
    }

    for (const auto& v : data | std::views::values)
        static_assert(std::is_reference_v<decltype(v)>);

    for (const auto& [k, v] : data)
        static_assert(std::is_reference_v<decltype(v)>);  // error

    {
        auto& kv = *data.begin();
        auto& [k, v] = kv;
        static_assert(std::is_reference_v<decltype(v)>);  // error
    }

    {
        auto kv = std::make_pair(3, 5);
        auto& k = kv.first;
        auto& v = kv.second;
        static_assert(std::is_reference_v<decltype(v)>);
    }

    return 0;
}

deduced types


1
你能添加准确的编译器错误信息吗?Intellisense 错误波浪线在这里并不是最终的决定。 - alter_igel
1
这与std::map无关。只是结构化绑定中的名称不是引用。相关/重复 https://dev59.com/x0kGtIcB2Jgan1znD7mK - cigien
@alterigel 在波浪线上有两个静态断言失败。 - kizer
@cigien 我简直不敢相信我忘了检查在最后一个块中 auto& [k2, v2] = kv; 会产生什么结果。这确实也会导致两个非引用。 - kizer
问题是为什么你在这里需要一个引用。每个结构化绑定引入一个匿名变量,如果使用auto&,它就是一个引用。kv是它的成员。您可以更改v,并且它将反映回map - n. m.
1个回答

3

这是一个引用。然而,有一条特殊规则,结构化绑定中的 decltype 会按照规范(来自于[dcl.type.decltype]/1.1)进行操作:

  • 如果 E 是未加括号的引用了结构化绑定的 标识表达式([dcl.struct.bind]),那么 decltype(E) 将被视为结构化绑定声明中所给出的引用类型;

对于 map 的 pair(它是一个 pair<Key const, Value>),其 引用 类型只是简单的 Key constValue,不可能是任何一种引用类型。


这是一个引用。如果v是一个引用,那么std::is_reference_v<decltype(v)>应该为真。 - n. m.
2
CWG2313 将它们更改为匿名引用绑定的对象的魔法 lvalue。 - Davis Herring
@DavisHerring 我觉得这样的区分对于它们的可用性而言没有实际意义——它们的行为就像是引用。我认为这里很不幸的是,decltype(v) 就像在撒谎一样,因为没有办法将结构化绑定向前传递。 - Barry
@n.1.8e9-where's-my-sharem。这是一个引用。正如我的回答所说,decltype(v)并不会给你一个引用类型,但这并不改变它在其他方面表现得像你期望的引用的事实。 - Barry
@Barry 它们的行为就像引用一样 什么意思:行为像引用是什么意思? - Language Lawyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接