6
votes

Utiliser auto pour une seule variable avec une liaison structurée

J'essaye de mettre à jour une variable passée à une fonction avec une liaison structurée:

std::tie(auto x, y) = func(y); // this does not work

Est-il possible d'éviter l'affectation supplémentaire y = y2 et d'utiliser quelque chose comme

[auto x, y] = func(y); // this does not work

ou

#include <iostream>
#include <tuple>
#include <utility>

std::pair<int, double> func(double y)
{
    return {1, 1.3+y};
}

int main() {
    double y = 1.0;
    auto [x, y2] = func(y);
    y = y2;
    std::cout << "x = " << x << ", y = " << y << '\n';
    return 0;
}


4 commentaires

Je vais demander l'évidence au cas où: vous ne pouvez pas simplement déplacer la déclaration de y vers la liaison structurée?


Je pense que l'idée est que y devrait déjà être déclaré car il est utilisé comme argument de func . Dans cet extrait de code, il pourrait être remplacé par auto [x, y] = func(1.0) , oui.


On dirait que des gens ont essayé de trouver quelque chose d'hybridation de liaisons structurées et de std::tie ici . Je ne sais pas si l'une de ces solutions vous sera très utile.


Dans auto [x, y] = foo() , auto ne s'applique pas à chaque identifiant individuel. Au lieu de cela, il s'applique à une seule variable invisible initialisée avec la valeur de retour de foo() . Les identifiants déclarés entre parenthèses deviennent (en gros) des alias magiques pour les membres de cette variable cachée. en.cppreference.com/w/cpp/language/structured_binding


3 Réponses :


2
votes

Une troisième option:

decltype(func(y).first) x;
std::tie(x, y) = func(y);


0 commentaires

1
votes

Pour répondre étroitement à votre question:

Non, vous ne pouvez pas réutiliser une variable existante dans une liaison structurée. La liaison structurée déclare toujours de nouvelles variables.

Cela étant dit, il existe d'autres options - comme std::tie , comme @Robert A l'a démontré.


0 commentaires

2
votes

Une liaison structurée est une déclaration ; il ne peut pas être utilisé par exemple pour l'affectation dans une variable déjà déclarée.

Si vous êtes autorisé à déplacer la déclaration de y et que vous n'en avez jamais besoin que pour faire un appel de fonction, vous pourriez abuser de la portée de la liste de capture d'un lambda immédiatement invoqué et le laisser s'observer (uniquement dans le cadre du lambda ) la variable y qui est déclarée dans le cadre d'une liaison structurée, qui est à son tour initialisée à l'aide du retour du lambda immédiatement appelé:

const auto l = [y = 1.0](){ return func(y); };
auto [x, y] = l();

Vous pouvez également utiliser un lambda nommé:

auto [x, y] = [y = 1.0](){ return func(y); }();
            // ^^^^^^^ actually not at all in namespace scope,
            //         but a data member of the closure type
            //         of the lambda expression.

Comme c'est généralement le cas avec l'observation aux côtés des règles de portée quelque peu complexes de C ++, cela ne fera que dérouter les lecteurs.


0 commentaires