C++17 fournira probablement un moyen générique d'interroger les fonctionnalités. Voir N4502 pour plus de détails, mais à titre d'exemple, considérez ce qui suit.
Cette partie est la partie constante, mettez-la dans un en-tête.
// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf.
template <typename...>
using void_t = void;
// Primary template handles all types not supporting the operation.
template <typename, template <typename> class, typename = void_t<>>
struct detect : std::false_type {};
// Specialization recognizes/validates only types supporting the archetype.
template <typename T, template <typename> class Op>
struct detect<T, Op, void_t<Op<T>>> : std::true_type {};
L'exemple suivant, tiré de N4502 montre l'utilisation :
// Archetypal expression for assignment operation.
template <typename T>
using assign_t = decltype(std::declval<T&>() = std::declval<T const &>())
// Trait corresponding to that archetype.
template <typename T>
using is_assignable = detect<T, assign_t>;
Par rapport aux autres implémentations, celle-ci est assez simple : un ensemble réduit d'outils ( void_t
y detect
) suffit. Par ailleurs, il a été rapporté (voir N4502 ) qu'il est mesurablement plus efficace (temps de compilation et consommation de mémoire du compilateur) que les approches précédentes.
Voici un exemple concret qui inclut des ajustements de portabilité pour GCC pre 5.1.
3 votes
C'est une bonne question. Je comprends assez bien SFINAE, mais je ne pense pas avoir jamais eu à l'utiliser (à moins que les bibliothèques le fassent sans que je le sache).
6 votes
La STL l'a formulé de manière légèrement différente dans FAQs ici "L'échec de la substitution n'est pas un éléphant".