(C++) Quelques questions sur la Métaprogrammation

Le problème exposé dans ce sujet a été résolu.

Salut tout le monde,
En ce moment je fais un peu de métaprogrammation en c++ depuis que j’ai regardé cette conférence (CppConf) et cet article sur developpez . com (Article)
J’ai plusieurs questions très différentes à poser :

1) Je ne comprend pas pourquoi ce code ne fonctionne pas :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
inline int doSomething()
{
    return 0;
}

int main()
{
   constexpr int value=doSomething(); // Erreur  apparemment, doSomething ne peut pas être évalué à la compilation.
   return 0;
}

Je sais que je devrais utiliser constexpr au lieu de inline mais vu que la fonction doSomething est inline et peut être exécuté à la compilation je ne comprend pas pourquoi ça ne marche pas.

2)Pourquoi les pointeurs dans les paramètres template doivent poivent pointer sur un objet "linkable".

1
2
3
4
5
6
7
template <const int *pointeur> struct Test{}
int main()
{
   const int tab[]={1,2,3,5};
   Test<tab> test // Erreur !!! tab n'a pas de linkage !
   return 0;
}

3) je voudrais approfondir mes connaissance sur les Templates (je sais le sujet est vaste ) ,est ce que C++ Templates - The Complete Guide serait un livre que vous me conseilleriez , sinon quelles lectures me conseilleriez vous ?

Bon lundi de Pâques à tous :)

+0 -0

Salut,

1) inline ne fait probablement exactement ce à quoi tu penses. Il était prévu à la base pour indiquer au compilateur qu’il est préférable d’inliner la fonction, mais rien ne force le compilateur à le faire. La seul chose vraiment importante à propos d’inline c’est que ça t’autorise à déclarer la même fonction dans plusieurs unités de compilations (ce qui n’est habituellement pas autorisé) qui sont linké dans le même programme. Pour le compilateur, appeler une fonction inline et écrire directement le contenu de la fonction à la place de l’appel sont deux choses différentes et seront traités différemment. Puisque ta fonction n’est pas déclaré constexpr, le compilateur refuse simplement de l’exécuter à la compilation (même si c’est possible). De la même manière, le compilateur refusera d’exécuter une fonction membre qui n’est pas marqué const sur un objet const, même si cette fonction membre ne modifie pas l’objet. Petite note: constexpr implique inline.

2) Dans ton exemple tab n’est pas connu à la compilation (tout simplement parce que le tableau est alloué sur la stack) et ne peux donc pas être utilisé en tant que paramètre de template. C’est exactement la même chose que pour cet exemple:

1
2
3
4
5
6
template <const int *pointeur> struct Test{};
int main() {
  const int a = 5;
  Test<&a> test;
  return 0;
}

Il toutefois possible d’utiliser un pointeur en temps qu’argument de template si l’adresse de ce pointeur est connu à la compilation, c’est-à-dire l’adresse d’une variable qui est déclaré directement dans un namespace:

1
2
3
4
5
6
7
const int a = 5;

template <const int *pointeur> struct Test{};
int main() {
  Test<&a> test; // autorisé
  return 0;
}

J’ai cependant du mal à voir dans quel circonstance c’est utile…

3) Je ne pas te conseiller de livre sur le C++ puisque je n’en ai jamais lu. En revanche, lorsque tu rencontres un problème avec le langage, je peux te suggérer d’aller lire la documentation (par exemple sur cppreference.com. C’est relativement difficile à comprendre au début parce qu’il n’y a pas vraiment de distinction entre les concepts importants et les trucs quasiment jamais utilisés. En revanche, avec un peu d’habitude ça permet de bien comprendre tous les détails de certains concepts et donc de voir pourquoi quelque chose ne fonctionne pas.

@Berdes : merci de m’avoir répondu, pour la 1) je pensais juste que lorsque la fonction était déclarée inline et suffisamment petite ,le compilateur l’inliner.
Merci encore pour ces précisions :)

EDIT : Après le livre c’était plus histoire de savoir comment utiliser les templates et les différents concepts qu’il y a derrière de manière optimale dans un projet .Dis moi si je me trompe mais je crois que cppreference présente de manière synthétique dans des exemple simples les différentes manière d’utiliser les template sans but précis , mais pas comment on pourrait les utiliser dans un projet.

+0 -0

je pensais juste que lorsque la fonction était déclarée inline et suffisamment petite ,le compilateur l’inliner.

Il faut distinguer ce que le compilateur fait et ce que le code dit pouvoir faire. Le compilateur va probablement inliner et tout remplacer par des constantes, mais le code dit qu’il ne faut pas considérer la fonction comme retournant une expression constante ; d’où l’erreur.

Après le livre c’était plus histoire de savoir comment utiliser les templates et les différents concepts qu’il y a derrière de manière optimale dans un projet.

Je n’ai pas lu le livre "C++ Templates - The Complete Guide", mais les initiateurs de Brigand on fait un livre sur la méta-programmation (lien du livre sur le dépôt). C’est de la méta-programmation par type avec des classes et des spécialisations de template. C’est intéressant de comparer les sources avec d’autres bibliothèques connues:

  • Metal qui se veut "pur", c’est à dire un code sans optimisation défigurant le code. Je crois que la seule concession se trouve sur fold. Toute les fonctions sont documentés.
  • Kvasir::mpl qui utilise le principe de continuation. Il vaut mieux lire le blog de l’auteur pour bien comprendre. Il l’utilise aussi pour ces projets (exemple: une version de std::tuple).
  • Boost.Hana qui contrairement au 3 autres est de la méta-programmation par valeur: des fonctions constexpr. La doc contient quelques usage possible. Le blog de l’auteur est aussi très intéressant.

C++ Templates - The Complete Guide commence à dater un peu je pense. Je l’avais trouvé bien quand je l’ai lu, il couvre les aspects techniques des templates et décrit les utilisations qu’on peut en faire. Cependant pour les aspects méta-programmations il reste assez succinct. Je le vois comme un ouvrage technique, pas un support d’apprentissage.

Pour l’utilisation des templates, j’avais apprécié Modern C++ Design et C++ Template Metaprogramming, mais ils commencent aussi tout les deux à dater. Je dirais que Modern C++ Design reste une bonne source aujourd’hui pour le fond, mais la forme des codes peut être revu avec les derniers outils du C++. Pour C++ Template Metaprogramming, même si le fond reste bon, je pense que les derniers éléments du langage changent la façon dont l’apprentissage peut être fait.

Edit: Je ne savais pas qu’une nouvelle édition avait été publiée.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte