Structured binding to replace std::tie abuse

前端 未结 3 1049
有刺的猬
有刺的猬 2020-12-10 05:54

In reading this summary of the c++17 final features I was a bit surprised by the section on structured bindings (emphasis mine):

structured bindi

3条回答
  •  抹茶落季
    2020-12-10 06:39

    I can put it simply like that:

    In a language where functions can return just one variable

    int a,b,c;
    std::tie(a,b,c) = function_returning_multiple_values();
    

    is a hack for:

    auto [a, b, c] = function_returning_multiple_values();
    

    just as in the hypothetical world where C++ would allow just one parameter for functions

    int p1, p2, p3;
    p1 = ...;
    p2 = ...;
    p3 = ...;
    
    function_taking_multiple_params(std::tie_params(p1, p2, p3));
    

    would be a hack for:

    function_taking_multiple_params(p1, p2, p3)
    

    You are so accustomed with the C++ restriction that a function can return at most one object, but in fact it is just an artificial language restriction, just as a restriction to accept at most one parameter would be an artificial language restriction.

    The std::tie is a library hack for a missing language feature. And it has some drawbacks:

    • the variables need be declared beforehand
    • the variable types must be declared explicitly
    • Inefficient or can't be used with types that are not default constructible

    Are structured bindings everything that they could have been? No, but for the most cases they are everything we need.

    What is missing?

    • Explicit type for some elements: e.g.:
    auto [a, std::string b, c] = foo();
    

    where a and c have the type deduced and b is explicit "std::string"

    • Nesting. E.g.:
    auto [a, [b1, b2], c] = foo();
    

    where the second returned object from foo is a tuple like object.

    • Language feature at the return site (bypassing std::tuple all together):
    auto foo() -> [int, int]
    

    instead of

    auto foo() -> std::tuple
    
    • Named return objects
    auto foo() -> [int& key, int& value]
    

    ... well... wouldn't that be nice

    • and combine that with... - get ready for a cool new name - Generalized return initialization:
    auto minmax_element(It begin, It end) -> [It min_it, It max_it];
    
    auto [min = *min_it, max = *max_it] = minmax_element(...);
    

提交回复
热议问题