Могу ли я вызвать во время выполнения логику для выбора определяемого пользователем литерала для вызова?

В моей программе на C++ у меня есть три пользовательских оператора:

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}; }

Длительность содержит количество часов (в виде числа с плавающей запятой) и флаг достоверности.

Так что я могу сказать: Duration duration = 17_m;

И я могу сказать: int m = 17; Duration duration = operator""_m(m);

Но я не могу сказать:

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

Я стремлюсь к чему-то в этом роде. operator""_() что я только что изобрел там, с компилятором, выбирающим во время выполнения соответствующий оператор для вызова. Я знаю, что мог бы написать что-то подобное сам (на самом деле я уже делал это в этом случае), но я не думаю, что что-то подобное уже есть в языке. Я прошу здесь подтвердить это: это на языке?

1 ответ

Вы хотите реализовать свой собственный парсер? Вот эскиз, который можно расширить до constexpr Мир:

#include <cassert>
#include <cstdlib>

#include <iostream>

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 {};
}

Если вас не волнует constexpr тогда вам следует использовать один из подходов более высокого уровня, предложенный в комментарии @RemyLebeau к этому ответу.

Другие вопросы по тегам