56 votes

fonction membre std :: tuple get ()

boost :: tuple a une fonction membre get () utilisée comme ceci:

 tuple<int, string, string> t(5, "foo", "bar");
cout << t.get<1>();  // outputs "foo"
 

Il semble que le std :: tuple C ++ 0x ne possède pas cette fonction membre et vous devez plutôt utiliser le formulaire de fonction non-membre:

 std::get<1>(t);
 

ce qui me semble plus laid.

Y a-t-il une raison particulière pour laquelle std :: tuple n'a pas la fonction membre? Ou est-ce juste ma mise en œuvre (gcc 4.4)?

68voto

doublep Points 9701

De brouillon C ++ 0x:

[Remarque: la raison pour laquelle get est une fonction non membre est que, si cette fonctionnalité avait été fournie en tant que fonction membre, le code dont le type dépendait d'un paramètre de modèle aurait dû utiliser le mot-clé template. - note de fin]

Ceci peut être illustré avec ce code:

 template <typename T>
struct test
{
  T value;
  template <int ignored>
  T&  member_get ()
  {  return value;  }
};

template <int ignored, typename T>
T&  free_get (test <T>& x)
{  return x.value;  }

template <typename T>
void
bar ()
{
  test <T>  x;
  x.template member_get <0> ();  // template is required here
  free_get <0> (x);
};
 

34voto

Nicol Bolas Points 133791

Les questions / réponses sont grands et certainement pour le comité des normes ont été essentielles à cette fin. Mais il y a un autre problème qui je pense est assez important de le mentionner.

Avec gratuit fonctions, vous avez la possibilité de modifier une interface sans modification de la définition d'une classe. Vous pouvez faire n'importe quel type "get" il suffit de par la spécialisation mondiale get. Avec une fonction membre, vous devez modifier directement la classe.

C'est une des raisons pour lesquelles basés sur la plage, for est construit sur std::begin/std::end au lieu de chercher des fonctions membres. std::begin/end sont spécialisés par type de matrice, de sorte que vous pouvez utiliser basés sur la plage, for avec des tableaux. Vous pouvez l'utiliser avec n'importe quel conteneur, même ceux qui n'ont pas d' begin/end fonctions. Vous pouvez vous spécialiser pour, par exemple, LibXML2 types d'éléments, de sorte que vous pouvez basés sur la plage, for sur xmlElement*s'.

Vous ne pouvez pas le faire s'ils devaient être des fonctions membres.

En C++, libre les fonctions sont une interface naturelle pour de nombreuses opérations qui pourraient être faites sur de nombreux types de classes.

12voto

Jerry Coffin Points 237758

N3090 / 3092, §20.4.2.6 / 8: "Remarque: La raison pour laquelle get est une fonction non membre est que si cette fonctionnalité avait été fournie en tant que fonction membre, le code dont le type dépendait d'un paramètre de modèle aurait dû être utilisé à l'aide du mot-clé template -fin note "

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