Benutzerdefinierte Literale müssen mit einem Unterstrich beginnen.
Dies ist eine mehr oder weniger allgemein bekannte Regel, die Sie auf jeder Website mit Laienwörtern finden, die über Benutzerliterale spricht. Es ist auch eine Regel, die ich (und möglicherweise andere?) Seitdem auf der Basis von "Was für ein Blödsinn" offen ignoriert habe. Das ist natürlich absolut nicht richtig. Im strengsten Sinne verwendet dies einen reservierten Bezeichner und ruft somit undefiniertes Verhalten auf (obwohl Sie vom Compiler praktisch nicht einmal ein Achselzucken bekommen).
Als ich überlegte, ob ich diesen (meiner Meinung nach nutzlosen) Teil des Standards weiterhin bewusst ignorieren sollte oder nicht, beschloss ich, mir anzusehen, was tatsächlich geschrieben wurde. Denn Sie wissen, was macht es aus , was jeder weiß . Was zählt, ist, was im Standard geschrieben ist.
[over.literal]
gibt an, dass "einige" Literal-Suffix-IDs reserviert sind, die mit verknüpfen [usrlit.suffix]
. Letzteres besagt, dass alle reserviert sind, mit Ausnahme derjenigen, die mit einem Unterstrich beginnen. OK, das ist so ziemlich genau das, was wir bereits wussten, explizit geschrieben (oder besser gesagt rückwärts geschrieben).
Auch [over.literal]
enthält einen Hinweis , die zu einer offensichtlich , aber beunruhigend Sache Hinweise:
Mit Ausnahme der oben beschriebenen Einschränkungen handelt es sich um normale Namespace-Scope-Funktionen und Funktionsvorlagen
Nun, sicher sind sie. Nirgends heißt es, dass dies nicht der Fall ist. Was würden Sie sonst von ihnen erwarten?
Aber warte einen Moment. [lex.name]
Gibt ausdrücklich an, dass jeder Bezeichner, der mit einem Unterstrich im globalen Namespace beginnt, reserviert ist.
Ein Literaloperator befindet sich normalerweise, sofern Sie ihn nicht explizit in einen Namespace einfügen (was meiner Meinung nach niemand tut!?), Sehr stark im globalen Namespace. Der Name, der mit einem Unterstrich beginnen muss , ist also reserviert. Eine besondere Ausnahme wird nicht erwähnt. Jeder Name (mit oder ohne Unterstrich) ist also ein reservierter Name.
Wird von Ihnen tatsächlich erwartet, dass Sie benutzerdefinierte Literale in einen Namespace einfügen, da für die "normale" Verwendung (Unterstrich oder nicht) ein reservierter Name verwendet wird?
_km
(für Kilometer) es in den Namespace udl
. Dann sieht ein Literal für 5km aus wie ... 5udl::_km
?
using
Aussagen da. In dem Bereich, in dem Sie das Literal verwenden müssen, haben Sie eine using-Anweisung, die es importiert.