Maison >développement back-end >C++ >Pourquoi `enable_if_t` échoue-t-il dans les définitions de fonctions ?

Pourquoi `enable_if_t` échoue-t-il dans les définitions de fonctions ?

DDD
DDDoriginal
2024-11-18 03:21:02332parcourir

Why Does `enable_if_t` Fail in Function Definitions?

Clash d'arguments de modèle : pourquoi activate_if_t échoue dans les définitions

Dans la programmation de modèles, il n'est pas rare de rencontrer des situations où nous devons activer conditionnellement ou désactivez les fonctions du modèle en fonction d'une condition spécifique. Dans de tels cas, le modèle std::enable_if est souvent utilisé pour y parvenir. Cependant, une tentative récente d'utiliser la syntaxe plus récente de std::enable_if_t a conduit à des erreurs inattendues.

Dans l'extrait de code ci-dessous, nous définissons deux fonctions de modèle f() en utilisant std::enable_if:

template<typename T,
         typename std::enable_if<std::is_same<int, T>::value>::type* = nullptr>
void f() { }

template<typename T,
         typename std::enable_if<std::is_same<double, T>::value>::type* = nullptr>
void f() { }

Lors du portage de ce code pour utiliser la nouvelle syntaxe std::enable_if_t, nous rencontrons un problème :

template<typename T,
         typename = std::enable_if_t<std::is_same<int, T>::value>>
void g() { }

template<typename T,
         typename = std::enable_if_t<std::is_same<double, T>::value>>
void g() { }

GCC se plaint avec l'erreur suivante :

error: redefinition of 'template<class T, class> void g()'
       void g() { }

Pour comprendre pourquoi cette erreur se produit, nous devons examiner la syntaxe des arguments du modèle. En supprimant le code inutile, nous avons la représentation simplifiée suivante de nos fonctions :

template<
  class T,
  class U/* = std::enable_if_t<std::is_same<int, T>::value>*/
>
void g() { }

template<
  class T,
  class U/* = std::enable_if_t<std::is_same<double, T>::value>*/
>
void g() { }

Il devient clair que les deux modèles sont du même type templatevoid(), quelles que soient leurs différentes valeurs par défaut. pour le deuxième argument de type. Cela entre en conflit avec l'exigence C selon laquelle deux fonctions de modèle du même type de modèle doivent avoir des signatures différentes.

Pour résoudre ce problème, nous pouvons remplacer le deuxième argument par un type de pointeur avec un type dépendant :

template<
  class T,
  std::enable_if_t<std::is_same<int, T>::value, int>* = nullptr
>
void f() { }

template<
  class T,
  std::enable_if_t<std::is_same<double, T>::value, int>* = nullptr
>
void f() { }

Dans ce code modifié, la signature des fonctions du modèle est désormais unique, éliminant le conflit et permettant la correspondance correcte du modèle.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn