Puis-je invoquer au moment de l’exécution la logique permettant de choisir le littéral défini par l’utilisateur à appeler?

Dans mon programme C ++, j’ai ces trois opérateurs littéraux définis par l’utilisateur:

constexpr Duration operator""_h(unsigned long long int count) { return {count / 1.f, true}; } constexpr Duration operator""_m(unsigned long long int count) { return {count / 60.f, true}; } constexpr Duration operator""_s(unsigned long long int count) { return {count / 3600.f, true}; } 

La durée contient un nombre d’heures (sous forme de float) et un indicateur de validité.

Je peux donc dire: Duration duration = 17_m;

Et je peux dire: int m = 17; Duration duration = operator""_m(m); int m = 17; Duration duration = operator""_m(m);

Mais je ne peux pas dire:

 const char* m = "17_m"; Duration duration1 = operator""_(m); const char* h = "17_h"; Duration duration2 = operator""_(h); 

Ce que je souhaite, c’est quelque chose comme cet operator""_() que je viens d’inventer là-haut, le compilateur sélectionnant au moment de l’exécution l’opérateur approprié à appeler. Je sais que je pourrais écrire quelque chose comme ceci moi-même (en fait, je l’ai déjà fait dans ce cas), mais je ne pense pas qu’une telle chose soit déjà dans la langue. Je demande ici à confirmer que: est-ce que c’est dans la langue?

Souhaitez-vous implémenter votre propre parsingur? Voici un croquis qui peut être étendu au monde de constexpr :

 #include  #include  #include  constexpr Duration parse_duration(const char* input) {// input: \A\d*_[hms]\z\0 int numeric_value = 0; // TODO: handle negative values, decimal, whitespace... std::size_t pos = 0; while(input[pos] != '_') { unsigned digit = unsigned(input[pos++]) - unsigned('0'); assert(digit <= 9); numeric_value *= 10; numeric_value += digit; } char unit = input[pos+1]; assert(input[pos+2] == '\0' && "must end with '\0' after one-letter unit"); switch(unit) { case 'h': return operator""_h(numeric_value); case 'm': return operator""_m(numeric_value); case 's': return operator""_s(numeric_value); default: std::cerr << unit << std::endl; } assert(false && "unknown unit"); return {}; } 

Si vous ne vous souciez pas de constexpr vous devez utiliser l'une des approches de niveau supérieur suggérée dans le commentaire de @ RemyLebeau sur cette réponse.