Mon objectif est d'avoir une struct qui prend un alias à un Voici un exemple du code que je voudrais écrire et c'est le résultat. J'utilise C ++ 14 et peut voler des implémentations de base des objets à partir de C ++ 17 aime la conjonction et Void_T p> Le ci-dessous fait ce que je veux, mais tbf i Je ne comprends pas vraiment comment. P> spécialisé enable_if_t code> avec un paquet de paramètres Varididic de typename et me dit ensuite si le
activer_if code> ' s Conditions étaient satisfaites pour tous les types dans le pack. J'ai un tas de ces
activisisés_if code> s, mais devez écrire des tests pour eux avant de pouvoir les mettre dans notre projet Open Source. J'ai environ 2000+ lignes de code testant manuellement ces spécialisations, mais je parie que je peux l'obtenir à 100 ou 200 si je peux comprendre le modèle ci-dessous. J'ai une version de travail (+ Godbolt Link), mais TBH Je ne sais pas pourquoi cela fonctionne et que ce régime est en train de casser dans un cas où la mise en œuvre reçoit un pack de paramètres
// Enable if for checking if all types are arithmetic
template <typename... Types>
using require_all_arithmetic = std::enable_if_t<conjunction<std::is_arithmetic<Types>...>::value>;
/// For the tests
TEST(requires, arithmetic_all_test) {
EXPECT_FALSE((require_variadic_tester<require_all_arithmetic, std::string,
Eigen::Matrix<float, -1, -1>>::value));
EXPECT_TRUE((require_variadic_tester<require_all_arithmetic,
double, int, float>::value));
}
3 Réponses :
template<template<class...> class Check, class... Ts> using require_variadic_tester = std::conditional_t<require_variadic_tester_impl<Check, Ts...>(42), std::true_type, std::false_type>;
Merci d'avoir répondu! J'ai besoin de la conjonction à l'intérieur de l'enable_if. J'ai mis à jour la question initiale avec plus de contexte
@Steve_corrin édité.
Wow! J'apprécie la réponse! Aussi mes excuses, le commentaire que j'ai mentionné ci-dessus était pour une autre réponse, mais rafraîchissant le post m'a fait jumblée. Votre méthode proposée est v nice, j'essaie de faire venir notre équipe pour aller jusqu'à C ++ 17 et voir un peu d'arrosage de consexpr étant cool peut aider à les convaincre un peu!
@Steve_corrin consexpr code> peut être utilisé dans
C ++ 14 code> (et c ++ 11 aussi). J'ai compilé les exemples avec
C ++ 17 code> pour
std :: conditionnel code>, c'est tout. Tout le reste doit être valide avec un compilateur complet en vedette
C ++ 14 CODE>.
Oh, je pensais que Constexpr était une utilisation limitée en C ++ 14 (uniquement dans les définitions de la fonction). J'ai l'impression que je leur ai essayé il y a quelque temps et que notre Windows construisait était vraisement malheureux. Je vais jouer avec ça!
Je ne sais pas de comprendre tous vos besoins, mais ...
Ce que je voudrais obtenir est un
exiger_varididic_tester code> qui prend dans un alias modélisé variadique, quelque chose comme
activer_if
> :: valeur> < / code>, et me donne vrai ou faux. Malheureusement, le renvoie ci-dessous faux, peu importe quels types sont entrés dans p> blockQuote> Êtes-vous sûr de vouloir
conjonction
> code>? p> ou voulez-vous
conjonction
...> code>? p> Je veux dire ... Le chèque doit recevoir une liste de types variadiques ou souhaitez-vous vérifier un alias, que (comme dans votre exemple) reçoit un type unique et une conjonction qui est true iff (si et seulement si) la vérification est satisfaite pour tous les types? p>
Dans ce second cas,
std :: void_t code> est très pratique pour Vérifiez que tous les chèques sont satisfaits. p>
Je propose le suivant
requir_varididic_impl code> et
require_variiadic_tester code> p>
xxx pré> Maintenant de p>
xxx pré> vous obtenez p>
xxx pré> pense que mon défaut de comprendre
void_t code> dans la première fonction méta est causant mon malentendu p> BlockQuote>
Essayez de penser
std :: Void_T
code> comme "Activer si tout TS code> est activé". p> p>
Merci d'avoir répondu! Le Void_T a plus de sens maintenant. Bien que j'ai besoin de la conjonction à l'intérieur de l'enable_if. J'ai mis à jour la question initiale avec plus de contexte
@Steve_corrin - Il me semble que vous avez besoin de Modèle
std :: void_t code>.
Je voudrais laisser le vide_t à l'extérieur de l'exigence_all_arithmétique car il n'est pas nécessaire lorsque nécessaire_ * s sont utilisés dans les modèles de fonctions
Voici ce qui se passe avec votre Ceci ne correspond pas à la spécialisation partielle de avec où la pièce intéressante est et seulement deux arguments de modèle explicite sont donnés, nous savons que les arguments de modèle réels sont SO Template Argument déduction Déduction < Code> Check = Exiger_arithmetic code> et d'autre part, si retour au Bien que je simplifie cela un peu: p> Le Votre Le modèle voir Le programme modifié sur Godbolt , avec les résultats souhaités. P> p> nécessitent_tester
requier_tester code>, qui a juste Arguments de deux modèles
check = require_arithmetic code>;
t = double code>;
Types = Double, Int Code>. Il ne correspond pas à la spécialisation partielle de
requiert_tester code>. Membre
valeur code> est le résultat de p>
requier_tester_impl
requir_tester_impl code> sont p>
requier_template_impl code>, nous essayons donc de correspondre à: p>
t1 = double code>. Le type
void_t
vérifier code> ou
t1 code>. Mais les valeurs de paramètres déduites doivent être remplacées dans, et nous trouvons
void_t
void_t
annulation code >. Ceci correspond à la
Void code> à partir des arguments de modèle, de sorte que la spécialisation partielle correspond à la correspondance, et
requier_template_impl
std :: true_type code>, pas
std :: faux_type code>. p>
t1 code> était
std :: string code> de
double code>, substituer les arguments de modèle déduits dans Wider (code> void_t
activer_if << / code> ...
> :: Type Code> Si aucun membre
type code> existe. Lors de la substitution des arguments de modèle déduits dans d'autres paramètres de modèle échouent, cela signifie que la spécialisation partielle est jetée comme non une correspondance. SO
nécessitent_template_impl
std :: faux_type code>. P>
Valeur Code> Membre de
Exiger_Tester CODE>, il trouve Récursivement (code> requis_tester
EXCEX_TESTER
requier_tester
requier_tester
code> est vraie. P>
vide code> est inutile dans la récursion code> requis_tester Code> et provoque l'étrange "fait" que
requier_tester
= vide par défaut code> à partir du modèle principal
EXCEPTE_TESTER CODE> et faites le boîtier de base
Modèle
expression code> dans l'expression
requier_tester code> donne toujours exactement deux arguments de modèle à
conjonction code>, donc ce n'est pas vraiment en train d'utiliser Sa propriété variadique, et vous pouvez aussi bien écrire
exiger_tester_impl << / code> ...
> :: valeur && requri_tester << / code> ...
> :: Valeur Code >. Étant donné que
exiger_tester code> fait une récursion elle-même, elle n'a pas besoin de la définition récursive abstraite dans
conjonction code>. Au lieu de cela,
requir_tester code> pourrait être simplifié pour compter sur
conjonction code> et éviter de faire une récursion elle-même: p>
requir_varididic_tester code> peut suivre un motif similaire, sauf que je vais donner le paramètre Modèle mannequin qui n'était que
typename = vide code> un nom, < Code> Typename Activer CODE>. Et il doit arriver avant le jeu de paramètres de modèle, il n'est donc pas utile de la défaut de défaut à
Void code>, et nous devons veiller à utiliser l'argument de modèle code> approprié code> Dans la position correspondante. P>
Cette réponse est magnifique, élégante, osez-moi dire même sexy. Merci beaucoup pour l'explication et le code !!
Pour répondre à votre première question: si
check code> est mal formé, puis
requier_tester_impl code> sera une dérivation de
faux_type code > Étant donné que la substitution des modèles échoue pendant la spécialisation, la réalisation de la mise en œuvre non spécialisée, alors que si elle est bien formée, elle sera spécialisée avec succès en tant que dérivation de
true_type code>.
Merci! Je pense que ce que je ne comprends pas spécifiquement, c'est pourquoi
check code> étant mal formé ne provoque pas que Sfinae s'en va et utilise la spécialisation non partielle.