Une sélective maison

Ce qui suit est directement pris d'une proposition de David Krauss en 2015.

Certains langages offrent la possibilité de réaliser des sélectives (en C++, des switch ... case) sur des types relativement complexes. C++, pour sa part, limite (en date de C++ 14) les sélective aux types entiers primitifs. Il est possible, même avec C++ 11, de simuler une sélective sur des types complexes, de manière à ce que :

Une implémentation possible serait :

#include <functional>
#include <initializer_list>
template<class oper, class comp = std::equal_to<>>
   class bound_comparison
   {
      comp c;
      oper o;
   public:
      bound_comparison(oper &&in_o, comp in_c = {})
         : o(std::forward<oper>(in_o)), c(std::move(in_c))
      {
      }
      template<class lhs>
         bool operator()(lhs const &l) const
            { return c(l, o); }
      bool operator()(std::initializer_list<std::decay_t<oper>> il) const
         { return std::find(il.begin(), il.end(), o) != il.end(); }
      std::decay_t<operand> const& get_value() const
         { return o; }
   };
template<class open, class comp = std::equal_to<>>
   bound_comparison<oper, comp> bind_comparator(oper &&o, comp c = {})
   {
      return{ std::forward<oper>(o), std::move(c) };
   }

Un code client possible serait :

#include <iostream>
#include <locale>
using namespace std;
int main()
{
   locale loc{ "" };
   auto case_ = bind_comparator(cin.get());
   if (case_('-')) {
      cout << "tiret" << endl;
   }
   else if (case_(48)) {
      cout << "neant" << endl;
   }
   else if (isspace(case_.get_value(), loc)) {
      cout << "une sorte de blanc..." << endl;
   }
   else if (case_({ 'X', 'x' })) {
      cout << "lettre mysterieuse" << endl;
   }
}

Simple mais charmant.


Valid XHTML 1.0 Transitional

CSS Valide !