Why can't I unpack entries of std::map into references?

Viewed 144

I have noticed that unpacking keys and values from std::map does not give me references. I am assuming that individual entries in std::map is stored as a pair of const key and value.

What works:

  • Manually taking .second of pair from std::map into reference.
  • Unpacking a pair made using std::make_pair into references.
  • Taking references from result of std::views::values

What doesn't work:

  • Directly unpacking map entries in for loop into references
  • Unpacking map entry obtained from iterator into references

Why do above two not work? Attached is a sample source code, and deduced types from the IDE. The compiler does result in same error messages with the insertions.

#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 Answers

It is a reference. However, there is a special rule that decltype on a structured binding does (from [dcl.type.decltype]/1.1):

  • if E is an unparenthesized id-expression naming a structured binding ([dcl.struct.bind]), decltype(E) is the referenced type as given in the specification of the structured binding declaration;

And the referenced types for a map's pair (which is a pair<Key const, Value>) are just Key const and Value, never any kind of reference.

Related