Pages

vendredi 30 novembre 2012

Déduction de type

Avec la nouvelle norme du C++ certains mots réservés se sont vu modifiés et de nouveaux mots-clefs sont apparus. C'est le cas de auto et decltype.

auto permet maintenant de ne pas indiquer de type lors de l'initialisation, le compilateur le faisant tout seul.

auto i = 8; // int
auto& x = i; // int&
auto p = new A; // A*
auto f = [](int n) { return n + 1; }; // quelque chose :)

decltype quant à lui permet de copier le type d'une variable ou d'une expression. Il s'utilise là où auto ne peut l'être, lors de la déclaration d'une variable.

decltype(f(8)) r; // int
decltype(x) ref; // int&

À noter que 2 parenthèses transforment le type en référence.

decltype((i)) a; // int&

Encore plus fort, auto et decltype peuvent être combinés pour déduire le retour d'une fonction.

template<typename _T, typename _U>
auto f(const _T& a, const _U&) -> decltype(a + b)
{ return a + b; }

dimanche 25 novembre 2012

Initialisation de membre non statique

Depuis gcc-4.7 il est possible d'initialiser des membres non statiques, ce qui simplifie l'écriture des constructeurs, notamment quand ceux-ci sont nombreux.
struct A {
  int i = 42;
} a; // initialise a.i avec 42

mardi 20 novembre 2012

Délégation de constructeur

Une belle nouveauté du langage est la délégation du constructeur
struct A {
 A(int);
 A(): A(42) { } // déléguer au constructeur A(int)
};

jeudi 15 novembre 2012

Héritage de constructeur

Une autre utilisation de using permet d'inclure les fonctions d'une classe parente dans la classe fille.

En C++11 cela s'étend aussi pour les constructeurs.

class A {
  int i;
public:
  A(int n)
  : i(n)
  {}
  //...
};
struct B : A {
  using A::A;
  //...
};
//...
B b(8);

Malheureusement pour ceux qui utilisent gcc, ce n'est disponible qu'à partir de la version 4.8.

samedi 10 novembre 2012

Alias templates

Ce message comme les quelques-uns qui suivront, sont dédiés aux nouveautés qu'apportent le C++11 et les parties déjà implémentées par gcc-4.7.

Pour aujourd'hui ce sera les alias sur templates. Qui n'a jamais eu envie de faire un typedef sur une structure template, définir quelques paramètres en dur et laisser les autres variables ? Définir par exemple une map qui contient des clefs en string et des valeurs définies par l'utilisateur ?

En C++89 c'est possible en passant par un intermédiaire: un trait.

template<typename _T>
struct build_map_key_string
{ typedef std::map<std::string, _T> type; };
//...
build_map_key_string<int>::type strmap;

Pas très beau :/.

Maintenant c'est possible de le faire de façon transparente, exactement comme avec un typedef. Sauf que typedef, en C++11, c'est dépasser, le nouveau mot clef à utiliser est using ‑même si pour la compatibilité typedef est toujours existant.

template<typename _T>
using map_key_string = std::map<std::string, _T>;
//...
map_key_string<int> strmap;

Simple et efficace !

J'hésitais à l’utiliser dans falcon mais depuis qu'un test echoué en gcc-4.6 est passé en gcc-4.7 je me suis mis à l'utiliser. Un exemple se trouve dans falcon/iterator/indirect_iterator.hpp où on peut voir un code vachement simplifié: un alias contre un héritage (les 2 y sont ;)). Je l'utilise également dans mon module property ce qui permet de simplifier l'utilisation compliquée d'une classe générique et cela de façon très élégante.

mardi 6 novembre 2012

Sed tout puissant

Il y 3 semaines environ je cherchais le moyen d'utiliser la commande sed avec une regex sur plusieurs lignes. En fait je voulais transformer tous les /\+\n\s+""/ en rien du tout (oui, les supprimer…). Sauf que comme tel, ça ne fonctionne pas, sed comme beaucoup de commandes unix fonctionne par ligne. Après de lourdes et pompeuses recherches d'au moins 7 secondes montre en main, je suis tombé sur la solution.

Pour ce faire, il suffit d'un identifiant, un petit label, une information de multi-ligne au milieu et 3 autres bricoles ; rien que ça :D.
Ce qui se traduit par:

sed -e :a -e N -e '$!ba' -e s'/\+\n\s+""//g'

Et en version courte:

sed ':a;N;$!ba;s/\+\n\s+""//g'

Je sais ce que vous vous demandez: pourquoi il n'y a pas -e dans la version courte ?
Mais parce que c'est la version courte, évidemment !

Sinon dans une moindre mesure.

:a
pour créer un identifiant, mais il peut très bien se nommer bidule
N
pour indiquer plusieurs lignes
$!ba
combinaison pour indiquer plein de choses, la seule dont je suis sûr c'est que b demande un identifiant (ici 'a')…

N peut être utilisé tout seul mais à ce moment c'est comme si on découpait le fichier par nombres de lignes égales à celle de la regex et qu'on les traitait indépendamment. Résultat, il peut y avoir des trous.

$ cat t
titi
titi
toto
titi
titi
$ sed ':a;N;$!ba;s/titi\ntiti/tutu/g' t
tutu
toto
tutu
$ sed 'N;s/titi\ntiti/tutu/g' t
tutu
toto
titi
titi

Et en bonus

sed 2,5s/e/U/g #remplace e par U à partir de la ligne 2 jusqu'à la 5.
sed "/$debut/,/$fin/"s/A/a/g #depuis $debut jusqu'à $fin.
sed "/$debut/,+5"s/A/a/g #depuis $debut et sur 5 ligne.