7
votes

C ++ Auto avec plusieurs choix

Au cours de mes aventures avec le projet, j'ai réalisé que je ne peux pas utiliser l'avantage du nouveau mot-clé Auto C ++ 11 si je veux initialiser le paramètre en fonction de la condition.

En gros, j'ai eu un extrait de code comme celui-ci : xxx

qui devait être remplacé par: xxx

mais j'ai besoin de déclarer le foo avec le type ( Comme le compilateur ne peut pas savoir que je vais utiliser le même type de retour. Je me demandais s'il y a un moyen d'utiliser le mot-clé auto dans ce cas. L'autre solution que j'ai trouvée utilise le? : opérateur avec ce code: xxx

mais s'il y a plus de deux fonctions à choisir, je ne veux pas vraiment chaîner le? : les opérateurs. Je me demande s'il y a un bon modèle à utiliser dans ce cas.


6 commentaires

C'est une honte de votre réserve à C ++ 11. En C ++ 14, utilisez une fonction ou une Lambda avec un type de retour déduit.


@MIKE Presque tous les compilateurs C ++ 11 ont pris en charge la déduction améliorée du type de retour sur Lambdas à peu près la porte.


La question est libellée un peu tort. Il n'y a pas de choix multiples. Le choix en est un, car tous les "chemins" évaluent au même type. Cependant, OP veut une sorte de "reporter" après la déclaration de déclaration variable. Pour plusieurs choix boost :: n'importe quel ou quelque chose du genre à ce que Woudl soit nécessaire.


@cerk comprenez-vous que les clauses si font l'affectation, tandis que la première clause simple (et la clause ? ) est la construction?


@Yakk: Cela peut être vrai (je ne connais pas chaque compilateur C ++ 11, donc ne peut pas commenter), mais la question est étiquetée "C ++ 11", pas "presque-tous-C ++ 11 -compilateur".


@Yakk je n'étais pas avant le moment où j'ai essayé de le compiler avec le type de retour de la const :: getfoo (). Ce qui fait mal les choses.


3 Réponses :


5
votes

C'est ce que déclinger est pour. Il vous fournira le type d'expression, sans évaluer réellement (et vous pouvez implémenter automatiquement en termes d'éteindre): xxx


3 commentaires

Cette approche ne fonctionnera pas pour les types de const en raison de la tâche modifiant leur contenu.


@Cerkiewny C'est une question sans rapport qui s'appliquerait également au cas où le type est réellement connu à l'avance et, auquel cas il serait probablement temps d'utiliser un ternaire ou s'il existe de nombreuses possibilités une Lamda. Vous pouvez utiliser le premier exemple de Yakks, mais remplacez la construction de si sinon.


@Lantant ce que je crois que Cerkhiewny fait référence à ce que RegelType () peut décider de décider, dites "const int &" (si c'est la valeur de retour) alors que l'automobile résolvait simplement à "INT", définissant une copie mutable (que je soutiendrais est le comportement correct dans ce cas). Vous pouvez résoudre ceci en utilisant Supprimer_Const et retirer les traits de référence, mais cela devient rapidement encombrant



7
votes

Votre instinct pour utiliser le? : Opérateur est correct - c'est une bonne idée d'initialiser une variable une seule fois et d'éviter le cycle de construction / d'affectation par défaut redondant.

Un moyen de faire cela consiste à différer la sélection de la création FOO à une petite fonction utilitaire: p> xxx pré>

Notez que, en raison de l'optimisation de la valeur de retour, cela est extrêmement efficace. p>

Si vous avez C ++ 14, il est même plus agréable - la fonction make_foo () peut Déduire son propre type de retour: P>

auto make_foo() {
    if (condition1()) {
        return bar::getfoo();
    }
    else if(condition2()) {
        return baz::getfoo();
    }
    else {
        return banana::getfoo();
    }
}


3 commentaires

Tout cela va bien, mais vous devez définir le type de retour de make_foo, de sorte qu'il vaincre le point de faire tout le travail car vous pouvez nommer le type de toute façon. Toute l'idée consiste à découpler le type de retour de la barre :: getfoo () et source de fichiers actuelle (donc lorsque vous le modifiez, vous n'avez pas besoin de modifier l'autre code source de fichiers, ce qui n'est pas le cas ici de la case C ++ 14 la résout mais c'est C ++ 14 que je ne peux pas utiliser)


@Cerkiewny OK Ceci peut être fait avec une petite édition, Sec ... FAIT


Même une ligne: retour de retour1 ()? Bar :: getfoo (): condition2 ()? Baz :: getfoo (): banane :: getfoo ();



4
votes
auto a = [&]{
  if (cond)
    return foo();
  else
    return bar();
}();

2 commentaires

Veuillez clarifier les besoins de vos besoins en bas de votre choix. Je n'ai pas vu de compilateur qui prend en charge Lambdas et que pas Soutenez cela.


@LFTICUS Il a besoin d'une déduction améliorée du type de retour pour Lambdas. Sous C ++ 11, la Lambdas consistant en une seule déclaration peut être déduite de type de retour. Sous C ++ 14, la déduction du type de retour Lambda que chaque compilateur C ++ 11 que j'ai jamais essayé est nécessaire (y compris ce qui précède), qui permet notamment de multiples déclarations. Le style C ++ 14 était (de ce que je peux rappeler) toujours destiné, mais le C ++ 11 "plus facile" a été mis en place (pour faciliter la mise en œuvre du compilateur). Apparemment, le style C ++ 14 était assez facile.