41 votes

Pourquoi «mutable» est-il un attribut de fonction lambda, au lieu d'être un type de capture?

Pourquoi c ++ 11 nous oblige-t-il à écrire:

 [a,b]() mutable { a=7; } // b is needlessly mutable, potential source of bugs
 

Au lieu de:

 [mutable a,b]() { a=7; } // no problems here
 

S'agit-il d'un oubli, jugé pas assez important, ou y a-t-il une raison technique spécifique?

18voto

Jesse Good Points 22971

Il y a une mention à propos de votre suggestion dans n2651:

La syntaxe pour les expressions lambda pourrait être étendu pour permettre de déclarer si la fermeture membres doivent être déclarés mutable ou pas.

Cette approche pourrait être source de confusion pour les programmeurs, comme la mutabilité n'est pas un propriété de la fermeture de l'objet, mais plutôt les variables stockées dans le de fermeture.

Je ne sais pas si c'est la seule raison, mais il ne semble pas comme il a été considéré. Cependant, Herb Sutter proposition, il lui suggère de se débarrasser de la mutable et de ne pas faire de la capture des copies implicitement const, donc on peut voir des changements.

6voto

Brandon Points 381

Probablement un oubli (de la même manière que les références rvalue ne peuvent pas être utilisées) et un artefact de la manière dont les lambdas sont implémentés de manière conceptuelle.

 int   a;
int*  b;
float c;

auto lambda1 = [&a, b, c](int d) mutable -> void {};

class lambda1 {
public:
    void operator()(int d) {}
private:
    int&  a_;
    int*  b_;
    float c_;
};

auto lambda2 = [&a, b, c](int d) -> void {};

class lambda2 {
public:
    void operator()(int d) const {}
private:
    int&  a_;
    int*  b_;
    float c_;
};
 

5voto

Andrew Durward Points 2012

L' mutable mot clé s'applique à l'objet généré par l'expression lambda et non pas individuellement les éléments capturés afin qu'il puisse être mis en œuvre par le compilateur à l'aide d'un const modificateur sur l' operator() méthode décrite dans la section 5.1.2, paragraphe 5 de la norme.

Cet appel de fonction de l'opérateur est déclarée const (9.3.1) si et seulement si le lambdaexpression du paramètre-déclaration de la clause n'est pas suivie par mutable.

Dans votre exemple, la classe générée par l'expression lambda pourrait ressembler à ceci:

class lambda
{
  int a, b;

public:

  lambda( int a, int b ) : a( a ), b( b ) {}

  void operator()() // non-const due to mutable keyword
  {
    a = 7;
  }
};

0voto

Dietmar Kühl Points 70604

L' mutable mot-clé n'est pas utilisée comme l' mutable mot-clé est normalement utilisé: Il est destiné à être à l'opposé de const dans ce cas et s'applique à la constness de l'appel de la fonction d'opérateur de l'implicite de la fonction de l'objet. Cependant, il était intentionnelle que l'appel de la fonction de l'opérateur de l'implicite de la fonction de l'objet est - const par défaut alors que normalement les fonctions membres sont non-const ("mutable"), mais par défaut. L'introduction de la lambda fonctions antérieurs à l'utilisation de mots clés contextuels (override et final) et l' mutable mot-clé semble être un meilleur choix que d' not const.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X