5

Since C++20, the concept of customization point is introduced in [namespace.std]/7:

Other than in namespace std or in a namespace within namespace std, a program may provide an overload for any library function template designated as a customization point, provided that (a) the overload's declaration depends on at least one user-defined type and (b) the overload meets the standard library requirements for the customization point. [ Note: This permits a (qualified or unqualified) call to the customization point to invoke the most appropriate overload for the given arguments. — end note ]

Does the note part (note the emphasized word "qualified") mean that std::f will automatically invoke the most appropriate overload for f if std::f is a customization point?

A real example is std::swap, which is a designated customization point. Does this mean since C++20, we can write std::swap(a, b) directly instead of using std::swap; swap(a, b);?

xskxzr
  • 12,442
  • 12
  • 37
  • 77
  • IANALL, but this new concept probably doesn't affect how ADL works so I would expect you still want an unqualified call. – jtbandes Feb 25 '20 at 03:15
  • @jtbandes Yes, ADL is still there, but there is [some trick](https://stackoverflow.com/a/53497055/5376789) that can make it possible for std::f to automatically invoke the most appropriate overload. – xskxzr Feb 25 '20 at 03:18
  • 1
    I've filed this as an issue: https://wg21.link/lwg3441 – mpark May 18 '20 at 00:07

1 Answers1

3

A real example is std::swap, which is a designated customization point. Does this mean since C++20, we can write std::swap(a, b) directly instead of using std::swap; swap(a, b);?

No. std::swap itself did not gain any powers. It's still just a function template, so if you call it directly, you're... calling it directly. No ADL or anything.

The point of this is to say how customization points should be opted into. That is, you write:

namespace N { // not std
    void swap(Foo&, Foo&);
}

Not:

namespace std {
    void swap(N::Foo&, N::Foo&);
}

Nor:

namespace std {
    template <>
    void swap(N::Foo&, N::Foo&);
}

However, C++20 does introduce a lot of new things called customization point objects which you can use directly do this kind of thing. The CPO for swap is spelled std::ranges::swap (and likewise there are CPOs for all the useful ranges things... ranges::begin, ranges::end, etc.).

Barry
  • 286,269
  • 29
  • 621
  • 977
  • The name `std::ranges::swap` is not introduced in [ranges], how strange! So what's the meaning of the note in [namespace.std]/7 while it explicitly states "[t]his permits a (**qualified** or unqualified) call ..."? – xskxzr Feb 25 '20 at 03:45
  • @xskxzr `std::iter_swap(x, y)` will find your `swap` too. – Barry Feb 25 '20 at 03:54
  • "That is, you write..." I don't think so, the note is saying "(qualified or unqualified) **call**", not about declarations. – xskxzr Feb 25 '20 at 04:03
  • @xskxzr And the rest of the paragraph talks about declaring this not in `std` (importantly, not as a specialization). – Barry Feb 25 '20 at 04:08
  • Yes, but now I'm confused about the note part. – xskxzr Feb 25 '20 at 04:12