C++ Logo

std-discussion

Advanced search

Re: 2 big problems with User Defined literals:

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Mon, 17 May 2021 21:27:52 -0400
On Mon, May 17, 2021 at 7:06 PM Andy Little via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> Personal opinions about whether UDLs are a prettier syntax for some or other purpose are interesting but not relevant.

UDLs are almost entirely a convenience notation. There is almost
nothing you can do with a UDL that you cannot reasonably do with a
direct function call (and personally, I think we should add C++
features to remove the "almost" from that sentence). As such, the
*only* reason why UDLs exist is "prettier syntax".

So questions about the prettiness or convenience of the syntax are
entirely relevant.

> UDL's were already considered and accepted as a C++ feature in the standard in form of time UDLs for h min s ms us ns. I and many others find these useful
> https://os.mbed.com/docs/mbed-os/v6.10/apis/thisthread.html
>
> I can of course define my own udls _h _min _s _ms _us _ns
>
> However, since UDL's can't be qualified, they will eventually collide with someone else's. This already occurred between std::chrono and potential std units libraries. This also occurs already when I seek to interop with other units library outside std.

That a collision of UDLs can happen is understood. The question I have
is *why* that collision happens.

The standard way of using UDLs is to perform a `using` declaration in
the function that wants to use those UDLs. Under this guidance, to get
a collision, you must have a function that needs to use literals from
two different literal groups.

My point is that such an eventuality ought to be quite rare. What are
you doing that this is a common occurrence?

Because I suspect that what you want is to just shove `using
literal-namespace` at the top of some header or .cpp file and expect
to be able to use any UDLs at any time. That is not a reasonable
expectation, and the feature was *not* designed with that expectation
in mind.

> units is just one example in the domain I have many years of experience in, but no doubt there are many others in other domains
>
> Sure it is inconvenient to have to be explicit about the qualifying namespace of the UDL you are using, but it should at least be possible and it should also be possible to look up overloaded UDLs without qualification or using statements in various contexts
>
> #include <iostream>
> #include <chrono>
>
> int main()
> {
> auto a = std::chrono::milliseconds{5};
> auto b = a + a; //this works fine
> auto c = a + 5ns; // so why not this?
> }

Because an expression has to be able to stand alone. This is
(partially) why we don't overload function calls on the basis of
return types. A function call expression gets resolved on the basis of
the types of its arguments, not on the basis of how its return value
gets used.

`5ns` has to resolve to the same function call regardless of how you use it.

Received on 2021-05-17 20:28:06