structured bindings with std::minmax and rvalues

前端 未结 2 939
清歌不尽
清歌不尽 2020-12-31 01:44

I ran into a rather subtle bug when using std::minmax with structured bindings. It appears that passed rvalues will not always be copied as one might expect. Or

2条回答
  •  醉梦人生
    2020-12-31 01:53

    What's important to note in auto [amin, amax] is that the auto, auto& and so forth are applied on the made up object e that is initialized with the return value of std::minmax, which is a pair. It's essentially this:

    auto e = std::minmax(3, 6);
    
    auto&& amin = std::get<0>(e);
    auto&& amax = std::get<1>(e);
    

    The actual types of amin and amax are references that refer to whatever std::get<0> and std::get<1> return for that pair object. And they themselves return references to objects long gone!

    When you use std::tie, you are doing assignment to existing objects (passed by reference). The rvalues don't need to live longer than the assignment expressions in which they come into being.


    As a work around, you can use something like this (not production quality) function:

    template
    auto as_value(std::pair in) {
        using U1 = std::decay_t;
        using U2 = std::decay_t;
        return std::pair(in);
    }
    

    It ensures the pair holds value types. When used like this:

    auto [amin, amax] = as_value(std::minmax(3, 6));
    

    We now get a copy made, and the structured bindings refer to those copies.

提交回复
热议问题