Répéter une tâche fois – operator "" _times

Ce qui suit est probablement un usage abusif des littéraux maison, mais c'est charmant alors j'espère que vous me le pardonnerez.

Répéter une tâche fois est simple : il suffit d'une boucle (typiquement une boucle à compteur) et d'une opération à réaliser :

#include <iostream>
using namespace std;
int main() {
   enum { N = 10 };
   for(int i = 0; i != N; ++i)
      cout << "J'aime mon prof" << endl;
}

Il est aussi facile de réaliser une telle tâche avec un foncteur et une opération (typiquement une λ) :

#include <iostream>
using namespace std;
class repeater {
   unsigned long long ntimes;
public:
   constexpr repeater(unsigned long long ntimes) : ntimes{ ntimes } {
   }
   template <class F> void operator()(F && f) {
      for(unsigned long long i = 0; i != ntimes; ++i) f();
   }
};
int main() {
   repeater{ 10 }([] { cout << "J'aime mon prof" << endl; });
}

L'étape suivante, qui me semble divertissante, est de générer le foncteur à l'aide d'un littéral maison :

#include <iostream>
using namespace std;
class repeater {
   unsigned long long ntimes;
public:
   constexpr repeater(unsigned long long ntimes) : ntimes{ ntimes } {
   }
   template <class F> void operator()(F && f) {
      for(unsigned long long i = 0; i != ntimes; ++i) f();
   }
};
constexpr repeater operator"" _times(unsigned long long n) {
   return{ n };
}
int main() {
   10_times([] { cout << "J'aime mon prof" << endl; });
}

Et enfin, de remplacer le foncteur par une λ :

#include <iostream>
using namespace std;
auto operator"" _times(unsigned long long n) {
   return [n](auto && f) { for (unsigned long long i = 0; i != n; ++i) f(); };
}
int main() {
   10_times([] { cout << "J'aime mon prof" << endl; });
}

... ce qui m'a fait sourire, alors voilà.

Lectures complémentaires

Quelques liens pour enrichir le propos.


Valid XHTML 1.0 Transitional

CSS Valide !