Literais definidos pelo usuário devem começar com um sublinhado.
Essa é uma regra mais ou menos universalmente conhecida que você pode encontrar em todos os sites leigos que falam sobre literais de usuários. É também uma regra que eu (e possivelmente outros?) Tenho ignorado descaradamente desde então em uma base "que besteira". Agora, é claro, isso estritamente não está correto. No sentido mais estrito, isso usa um identificador reservado e, assim, invoca o Comportamento indefinido (embora você não receba quase nada do compilador, praticamente).
Então, pensando se devo continuar a ignorar deliberadamente que (na minha opinião é inútil) parte do padrão ou não, decidi examinar o que realmente está escrito. Porque, você sabe, o que importa o que todo mundo sabe . O que importa é o que está escrito no padrão.
[over.literal]
afirma que "alguns" identificadores de sufixo literais estão reservados, vinculados a [usrlit.suffix]
. O último afirma que todos são reservados, exceto aqueles que começam com um sublinhado. OK, é exatamente o que já sabíamos, escrito explicitamente (ou melhor, escrito de trás para frente).
Além disso, [over.literal]
contém uma Nota que sugere uma coisa óbvia, mas preocupante:
exceto pelas restrições descritas acima, são funções comuns de escopo de espaço para nome e modelos de função
Bem, claro que são. Em nenhum lugar diz que eles não são, então o que mais você espera que eles sejam.
Mas espere um momento. [lex.name]
afirma explicitamente que cada identificador que começa com um sublinhado no espaço para nome global é reservado.
Agora, normalmente, um operador literal, a menos que você o coloque explicitamente em um espaço para nome (o qual, acredito que ninguém o faça !?), está muito no espaço para nome global. Portanto, o nome, que deve começar com um sublinhado, é reservado. Não há menção de uma exceção especial. Portanto, todo nome (com sublinhado ou sem) é um nome reservado.
Você realmente deve colocar literais definidos pelo usuário em um espaço para nome porque o uso "normal" (sublinhado ou não) está usando um nome reservado?
_km
(por quilômetros) no espaço para nome udl
. Então um literal para 5 km parece ... 5udl::_km
?
using
servem as declarações. No escopo em que você precisa usar o literal, tenha uma instrução using que o importe.