Il y a 2 problèmes difficiles en informatique: l'invalidation du cache, le nommage des choses et les erreurs ponctuelles.
Il s'agit du 2ème problème: nommer les choses.
Je cherche si cette technique ou ce type a déjà été utilisé ailleurs et a un nom. dichotomy
est un nom correct, mais bools_at_compile_time
est horrible.
using dichotomy_t = std::variant<std::false_type, std::true_type>;
// (or a struct that inherits from that, and overloads operator bool())
constexpr dichotomy_t dichotomy( bool b ) {
if (b) return std::true_type{};
return std::false_type{};
}
template<class F, class...Bools>
constexpr auto bools_at_compile_time( F&& f, Bools...bools ) {
static_assert( (std::is_same<Bools, bool>{} && ...) );
return std::visit( std::forward<F>(f), dichotomy(bools)... );
}
dichotomy_t
est une variante entre vrai et faux. Sa représentation d'exécution est 0
ou 1
.
Cela vous permet de faire:
auto foo( bool x, bool y ) { // <-- x and y are run-time bools here
auto func = [&](auto x, auto y) {
return some_template<x,y>(); // <-- x and y are compile-time bools here
};
return bools_at_compile_time( func, x, y ); // <-- converts runtime to compile time bools
}
Y a-t-il un nom pour dichotomy_t
ou plus général bools_at_compile_time
technique? Je recherche un nom bien connu dans n'importe quelle communauté (même non C++), même un verbe qui décrit "prendre une valeur d'exécution et créer un commutateur et un ensemble de valeurs de temps de compilation dans le code généré pour choisir entre "mieux qu'une phrase.
Une bonne réponse comprendrait le nom, des citations/citations décrivant ce que signifie ce nom, des exemples de cette chose nommée utilisée dans l'autre contexte, et la preuve que ce nom est équivalent ou inclus dans le type/la valeur et la fonction ci-dessus.
(Il peut être utile de trouver un nom dont la généralisation serait un enum
au lieu d'un bool
, qui a un nombre fixe d'états connus, et une carte commutateur/cas qui convertit le runtime dans une constante de compilation dans chaque clause case.)
Je ne connais aucun nom existant pour ce modèle, mais si vous regardez bien comment la STL nomme les choses, vous pouvez utiliser un nom assez proche pour rendre votre code explicite.
J'ai aussi aimé l'idée dispatcher_t
De @ Jarod42, je pense qu'elle est plus générique que dichotomy_t
Ou n_chotomy_t
.
dichotomy()
pourrait s'appeler make_variant(b)
. Puisqu'il renverra la valeur std::variant
D'un booléen donné en argument. Tout comme std::make_Tuple
Crée un Tuple à partir de plusieurs arguments.
Je suggère de remplacer bools_at_compile_time
Par static_eval
. Tout comme static_assert
Fait une assertion au moment de la compilation.
Ce n'est pas que si eval
n'est pas le bon adjectif pour votre cas d'utilisation, vous pouvez facilement l'adapter static_*
.
#include <type_traits>
#include <variant>
#include <utility>
using dichotomy_t = std::variant<std::false_type, std::true_type>;
// (or a struct that inherits from that, and overloads operator bool())
constexpr dichotomy_t make_variant( bool b ) {
if (b) return std::true_type{};
return std::false_type{};
}
template<class F, class...Bools>
constexpr auto static_eval( F&& f, Bools...bools ) {
static_assert( (std::is_same<Bools, bool>{} && ...) );
return std::visit( std::forward<F>(f), make_variant(bools)... );
}
template<bool x, bool y>
auto some_template() {
return x || y;
}
auto foo( bool x, bool y ) { // <-- x and y are run-time bools here
auto func = [&](auto x, auto y) {
return some_template<x,y>(); // <-- x and y are compile-time bools here
};
return static_eval( func, x, y ); // <-- converts runtime to compile time bools
}
#include <iostream>
int main() {
std::cout << foo( true, true ) << "\n";
}
La génération d'une version spécialisée d'une fonction est appelée clonage . (voir Clonage de procédure ). Le terme clone est utilisé pour nommer la fonction spécialisée générée par l'optimiseur pendant une propagation constante (voir doc gcc ).
L'ensemble des fonctions spécialisées générées par std::visit
pourrait être nommé ensemble de clones .
Cet ensemble est généré pour toutes les combinaisons de la valeur d'argument. Cette combinaison de termes supposons que l'ensemble des valeurs possibles de chaque argument est fini.
Nous pourrions donc avoir un nom long pour l'ensemble de clones comme, ensemble de clones pour toutes les combinaisons de valeurs d'argument . Une autre option plus obscure mais plus courte pourrait être l'ensemble de clones combinatoires .
Comme déjà souligné, l'action de sélectionner la bonne fonction à appeler en terme d'argument pourrait être appelée dispatch .
Je proposerais donc combinatiorial_clone_set_dispatch
ou dispatch_in_combinatorial_clone_set
...
Comme je ne suis pas au courant d'une implémentation similaire, je vais simplement taper par type avec des couleurs de bikeshed.
using boolean_t = std::variant<std::false_type, std::true_type>;
C'est assez explicite, car c'est une variante qui peut stocker l'un ou l'autre des std::integral_constant
s pour vrai ou faux. C'est une sorte de bool
, mais bool_t
est susceptible de créer de la confusion. Une alternative est boolean_variant
, mais cela peut être trop verbeux.
constexpr boolean_t to_boolean_t( bool b ) {
if (b) return std::true_type{};
return std::false_type{};
}
J'ai commencé avec convert_bool
, mais c'est un peu trop générique. to_boolean_t
est plus expressif. make_boolean_t
est également une possibilité, car il s'agit essentiellement d'un boolean_t
fonction d'usine. Remarque: j'ai précédemment choisi to_constexpr_boolean
, mais c'est inutilement verbeux.
template<class F, class...Bools>
constexpr auto static_eval( F&& f, Bools...bools ) {
static_assert( (std::is_same<Bools, bool>{} && ...) );
return std::visit( std::forward<F>(f), to_boolean_t(bools)... );
}
J'ai choisi static_eval
ici comme j'aime le raisonnement de Clonk, mais "statique" a une signification contextuelle en C++, donc les alternatives sont (sans ordre d'importance):
boolean_visit
static_visit
constexpr_eval
constexpr_visit
Votre problème était: (le mien en gras)
Je cherche un nom qui est bien connu dans n'importe quelle communauté (même non C++), même un verbe qui décrit "en prenant une valeur d'exécution et en créant un commutateur et un ensemble de valeur de temps de compilation dans généré code à choisir "mieux qu’une phrase.
Il y en a, mais seulement si vous l'adoptez dans un domaine scientifique connexe:
Le National Electrical Code (NEC) des États-Unis définit un tableau de distribution comme "un grand panneau unique, un cadre ou un assemblage de panneaux sur lesquels sont montés, sur la face, l'arrière ou les deux, des interrupteurs, des dispositifs de protection contre les surintensités et d'autres dispositifs de protection, des bus, et généralement des instruments ". Le rôle d'un tableau est de permettre la division du courant fourni au tableau en courants plus petits pour une distribution ultérieure et de fournir une commutation, une protection de courant et (éventuellement) une mesure pour ces différents courants. En général, les tableaux de distribution peuvent distribuer de l'énergie aux transformateurs, aux tableaux de distribution, à l'équipement de contrôle et, en fin de compte, aux charges individuelles du système.
En adoptant cette pensée, vous l'appelleriez simplement commutateurs.
J'ajouterai également qu'il est assez inhabituel de spécifier (c'est-à-dire répéter ) le type de stockage ou le qualificatif cv, etc. dans les noms de type/variable - même lorsqu'il n'est pas directement visible, vous laisseriez généralement cela implicite - à moins qu'il ne soit vraiment nécessaire de le souligner.
Peut-être staticCastValue? Comme dans vous convertissez une valeur dynamique (runtime) en une valeur statique. Peut être utilisé avec des modèles ou des surcharges pour différents types.
Ou peut-être affirmer inmutable? Comme vous convertissez un type mutable en un type inmutable.
Ou peut-être exprimer constamment? Comme en vous exprimez la même valeur mais sous une forme constante. Une forme similaire à constexpr.
Un sauvage: staticBifurcate? Comme il y a deux choses à choisir, une bifurcation est donc là.
verbe bifurqué/ˈbʌɪfəkeɪt/1. diviser en deux branches ou fourchettes. "juste en dessous du Caire, la rivière bifurque"
Ou enfin convertToConstExpr? Dire explicitement que la valeur sera convertie en quelque chose de semblable ou compatible avec un constexpr.