Structured binding in C++/WinRT: The key-value pair

Raymond Chen

Last time, we learned how to add structured binding support to your own types, and noted that the get functions do not have to return references.

C++/WinRT has something similar to a std::pair: The IKeyValuePair<K, V>, which is used to represent a single entry in a map. (C++ uses a std::pair for this.)

Since the kvp.Key() and kvp.Value() methods always return by value, it means that when you use structured binding on an IKeyValuePair, the variables are always copies. The qualifiers on the auto merely describes how the kvp itself is captured.

IKeyValuePair<hstring, int32_t> kvp;
auto& [key, value] = kvp;

This looks like it’s binding key and value as lvalue references, but it’s not. They are non-reference variables. That’s because the code expands to

auto& hidden = kvp;
decltype(auto) key = kvp.Key();
decltype(auto) value = kvp.Value();

Since the results stored into key and value don’t depend on how you bound the source, you may as well bind the hidden variable by reference to avoid an unnecessary copy.

// wasteful copy from kvp to hidden
auto [key, value] = kvp;

// non-copying binding
auto&& [key, value] = kvp;

Bonus chatter: The structured binding of IKeyValuePair comes in particularly handy when you are iterating over something like an IMap:

for (auto&& [key, value] : map)
{
  // use key and value
}

3 comments

Discussion is closed. Login to edit/delete existing comments.

  • Buster C 0

    Same typo as in Wednesday’s table? Shouldn’t it be:

    auto& hidden = kvp;
    decltype(auto) key = hidden.Key();
    decltype(auto) value = hidden.Value();
    
    • Jeremy Richards 0

      My best guess, is that the auto& hidden extends the lifetime of kvp in case it is a temporary. Disclaimer: I am no C++ language lawyer and it has been 8 years or so since I used C++ on a daily basis. (Or it could be a typo)

      • anonymous 0

        this comment has been deleted.

Feedback usabilla icon