How can I emulate destructuring in C++?

后端 未结 5 1219
轻奢々
轻奢々 2020-12-29 01:44

In JavaScript ES6, there is a language feature known as destructuring. It exists across many other languages as well.

In JavaScript ES6, it looks like this:

相关标签:
5条回答
  • 2020-12-29 01:50

    In C++17 this is called structured bindings, which allows for the following:

    struct animal {
        std::string species;
        int weight;
        std::string sound;
    };
    
    int main()
    {
      auto pluto = animal { "dog", 23, "woof" };
    
      auto [ species, weight, sound ] = pluto;
    
      std::cout << "species=" << species << " weight=" << weight << " sound=" << sound << "\n";
    }
    
    0 讨论(0)
  • 2020-12-29 01:54

    For the specific case of std::tuple (or std::pair) objects, C++ offers the std::tie function which looks similar:

    std::tuple<int, bool, double> my_obj {1, false, 2.0};
    // later on...
    int x;
    bool y;
    double z;
    std::tie(x, y, z) = my_obj;
    // or, if we don't want all the contents:
    std::tie(std::ignore, y, std::ignore) = my_obj;
    

    I am not aware of an approach to the notation exactly as you present it.

    0 讨论(0)
  • 2020-12-29 02:06

    I am afraid you cannot have it the way you are used to in JavaScript (which by the way seems to be new technology in JS). The reason is that in C++ you simply cannot assign to multiple variables within a structure/object/assignment expression as you did in

    var {species, sound} = animal
    

    and then use species and sound as simple variables. Currently C++ simply does not have that feature.

    You could assign to structures and/or objects whilst overloading their assignment operator, but I don't see a way how you could emulate that exact behaviour (as of today). Consider the other answers offering similar solutions; maybe that works for your requirement.

    0 讨论(0)
  • 2020-12-29 02:08

    Mostly there with std::map and std::tie:

    #include <iostream>
    #include <tuple>
    #include <map>
    using namespace std;
    
    // an abstact object consisting of key-value pairs
    struct thing
    {
        std::map<std::string, std::string> kv;
    };
    
    
    int main()
    {
        thing animal;
        animal.kv["species"] = "dog";
        animal.kv["sound"] = "woof";
    
        auto species = std::tie(animal.kv["species"], animal.kv["sound"]);
    
        std::cout << "The " << std::get<0>(species) << " says " << std::get<1>(species) << '\n';
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-29 02:08

    Another possibility could be done as

    #define DESTRUCTURE2(var1, var2, object) var1(object.var1), var2(object.var2)
    

    which would be used like:

    struct Example
    {
        int foo;
        int bar;
    };
    
    Example testObject;
    
    int DESTRUCTURE2(foo, bar, testObject);
    

    yielding local variables of foo and bar.

    Of course it's limited to creating variables all of the same type, although I suppose you could use auto to get around that.

    And that macro is limited to doing exactly two variables. So you would have to create DESTRUCTURE3, DESTRUCTURE4, and so on to cover as many as you want.

    I don't personally like the code style this ends up with, but it comes reasonably close to some of the aspects of the JavaScript feature.

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