C++17 structured binding that also includes an existing variable

后端 未结 2 1599
谎友^
谎友^ 2020-12-11 01:20

This SO answer lists some shortcomings of C++17 decomposition declarations (the feature formerly known as \"structured binding\"). For example, you can\'t give explicit type

相关标签:
2条回答
  • 2020-12-11 01:33

    In cases with more complex types, a simple workaround of a movable temporary new object might be the simplest desirable step in the direction of what you want (though I reckon in your particular case it might be simpler to stick to traditional tie instead):

    ... // (as in your code: p & end exist already, key & p_ not yet)
    
    auto [key, p_] = load_string(p, end);
    p = move(p_);
    
    ... // (continue using p)
    

    I'm sorry I eventually couldn't compile it myself though I could see it being a problem of my IDE (CLion which currently only halfly supports C++17) though I'd expect it to work in general.

    0 讨论(0)
  • 2020-12-11 01:55

    This is a really dumb idea that I wouldn't seriously suggest unless there ends up being no sane workaround... but consider the following code.

    template<size_t P, size_t... Is>
    auto plus(std::index_sequence<Is...>)
    {
        return std::index_sequence<P+Is...>{};
    }
    
    template<typename RHS, size_t... Is>
    auto tuple_select(RHS&& rhs, std::index_sequence<Is...>)
    {
        return std::forward_as_tuple(std::get<Is>(std::forward<RHS>(rhs))...);
    }
    
    template<typename... Ts>
    struct AndTie {
        std::tuple<Ts&...> v;
        AndTie(Ts&... vs) : v(vs...) {}
    
        template<typename RHS>
        auto operator=(RHS&& rhs) && {
            constexpr int N = std::tuple_size_v<RHS>;
            constexpr int K = sizeof...(Ts);
            v = tuple_select(std::forward<RHS>(rhs), plus<N-K>(std::make_index_sequence<K>{}));
            return tuple_select(std::forward<RHS>(rhs), std::make_index_sequence<N-K>{});
        }
    };
    

    This gives us

    auto [key] =AndTie(p)= load_string(p, end);
    auto [value] =AndTie(p)= load_value(p, end);
    

    It still has the limitation that the "tied" lvalues are constrained to appear last and the "declared" variables are constrained to appear first, but I don't think there's much way to get around that. And something like tuple_shuffle<Is...> could handle that if you needed it.

    0 讨论(0)
提交回复
热议问题