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.