4 votes

Que fait template<class = enable_if_t<...>>?

J'ai lu des fichiers STL pour apprendre de meilleures façons de formater mon code et pour apprendre des astuces pour être plus efficace. J'ai lu les fichiers de fil et je ne peux pas comprendre ce que fait une partie du code.

template, thread>::value>>
    explicit thread(_Fn&& _Fx, _Args&&... _Ax)
    {   // construct with _Fx(_Ax...)
    ...
    }

std::enable_if_t est

template
    using enable_if_t = typename enable_if<_Test, _Ty>::type;

template
    struct enable_if
    {   // type is _Ty for _Test
    using type = _Ty;
    };

Ce code est protégé par des droits d'auteur dans les STL de thread et str1common.

Ma seule question est : que fait class = enable_if_t<...>?

4voto

max66 Points 4276

Cherchez S.F.I.N.A.E. : "Substitution Failure Is Not An Error".

Voyez une implémentation possible de std::enable_if (std::enable_if_t n'est qu'une aide using, introduite en C++14, pour accéder au type de manière plus simple)

template
struct enable_if {};

template
struct enable_if { typedef T type; };

Est faite ainsi iff (if and only if) la valeur booléenne du template (le premier paramètre de template) est true, std::enable_if<...>::type est défini (avec le type dans le deuxième paramètre de template ; void si non exprimé).

Pour simplifier, vous avez que, dans votre exemple

template, thread>::value>>
    explicit thread(_Fn&& _Fx, _Args&&... _Ax)
    {   // construct with _Fx(_Ax...)
    ...
    }

enable_if_t (qui est typename std::enable_if<...>::type) est disponible si et seulement si la première valeur (!std::is_same::type, thread>::value) est true.

C'est-à-dire:

  • si !std::is_same::type, thread>::value est true, la substitution class = enable_if_t, thread>::value>> est effectuée et la fonction est implémentée

  • si !std::is_same::type, thread>::value est false, la substitution class = enable_if_t, thread>::value>> échoue, la fonction n'est pas implémentée mais ce n'est pas une erreur (SFINAE).

Pourquoi le langage permet-il cela?

Parce que, par exemple, vous pouvez implémenter deux versions de la fonction

template, thread>::value>>
    explicit thread(_Fn&& _Fx, _Args&&... _Ax)
    { /* faire quelque chose */ }

template, thread>::value>>
    explicit thread(_Fn&& _Fx, _Args&&... _Ax)
    { /* faire quelque chose d'autre */ }

Suggestion : cherchez SFINAE et étudiez-le car c'est une partie importante du C++ moderne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X