Comment puis-je émuler la déstructuration en C++?

Dans JavaScript ES6, il existe une fonctionnalité de langage appelée déstructuration . Il existe dans de nombreuses autres langues.

En JavaScript ES6, cela ressemble à ceci:

var animal = {
    species: 'dog',
    weight: 23,
    sound: 'woof'
}

//Destructuring
var {species, sound} = animal

//The dog says woof!
console.log('The ' + species + ' says ' + sound + '!')

Que puis-je faire en C++ pour obtenir une syntaxe similaire et émuler ce genre de fonctionnalité?

31
demandé sur Peter Mortensen 2015-07-14 01:22:36

5 réponses

Pour le cas spécifique des objets std::tuple (ou std::pair), C++ offre le std::tie fonction qui semble similaire:

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;

Je ne suis pas au courant d'une approche de la notation exactement telle que vous la présentez.

33
répondu Escualo 2015-07-13 22:39:39

En C++17, cela s'appelle liaisons structurées , ce qui permet ce qui suit:

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";
}
23
répondu dalle 2016-12-01 15:10:43

Surtout là avec std::map et 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;
}
6
répondu Chad 2015-07-13 22:39:34

J'ai peur que vous ne puissiez pas l'avoir comme vous êtes habitué en JavaScript (ce qui semble être Une nouvelle technologie dans JS ). La raison en est qu'en C++ vous ne pouvez tout simplement pas assigner à plusieurs variables dans une expression structure/objet/affectation comme vous l'avez fait dans

var {species, sound} = animal

Puis utilisez species et sound commevariables simples . Actuellement, C++ n'a tout simplement pas cette fonctionnalité.

Vous pouvez assigner des structures et / ou des objets tout en surchargeant leur affectation opérateur, mais je ne vois pas comment vous pourriez émuler ce comportement exact (à partir d'aujourd'hui). Considérez les autres réponses offrant des solutions similaires; peut - être que cela fonctionne pour votre exigence.

2
répondu Ely 2015-07-14 14:12:46

Une autre possibilité pourrait être faite comme

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

, Qui serait utilisé comme:

struct Example
{
    int foo;
    int bar;
};

Example testObject;

int DESTRUCTURE2(foo, bar, testObject);

Produisant des variables locales de foo et bar.

Bien sûr, il est limité à créer des variables du même type, bien que je suppose que vous pourriez utiliser auto pour contourner cela.

Et cette macro est limitée à faire exactement deux variables. Vous devez donc créer DESTRUCTURE3, DESTRUCTURE4, et ainsi de suite pour en couvrir autant que vous le souhaitez.

Je n'aime pas personnellement le code style cela finit par, mais il est raisonnablement proche de certains des aspects de la fonctionnalité JavaScript.

1
répondu TheUndeadFish 2015-07-16 07:31:19