Действительно ли мне нужно указывать каждую перегрузку вручную?
Да.
Литеральные операторы не вызываются с помощью разрешения перегрузки (не совсем). Разрешение перегрузки может делать такие вещи, как неявное преобразование или другие неприятные вещи. Поскольку литеральные операторы (как правило) вызываются компилятором для значений, сгенерированных во время компиляции, рекомендуется убедиться, что писатель литерального оператора получает литеральное значение whole (так же, как компилятор может предоставить, конечно) не преобразованное значение.
Это на самом деле довольно важно. Рассмотрим случай, когда вы хотите написать литерал, который принимает целочисленные значения, но , а не значения с плавающей точкой. То есть 12.3_lit
должно быть ошибкой компиляции. Ваша подпись для вашего оператора займет unsigned long long
, но long double
неявно преобразуется в unsigned long long
. Следовательно, 12.3_lit
будет действительным, если вы не хотите, чтобы оно было.
Теперь теоретически вы можете избежать такого сценария ios, = delete
явно используя сигнатуры с плавающей точкой. Но ... UDL были изобретены в то время, когда = delete
на самом деле не было чем-то особенным, так что это не обязательно было вариантом.
Чтобы избежать этого сценария ios, логический оператор диспетчерской логики c явно ищет определенный набор сигнатур (в зависимости от типа обрабатываемого литерала). Если у вас нет перегрузки long double
для оператора (или необработанной буквенной версии), то при обнаружении 12.3_lit
система не найдет подходящей функции и выдаст ошибку компиляции.
Поскольку система ищет указанные c сигнатуры, а не использует разрешение перегрузки, сигнатуры литеральных операторов (включая шаблоны) ограничены точным и только сигнатурами, которые будет искать логический оператор диспетчерской логики c для . Не больше, не меньше.