Why std::allocator<T>::allocate calls ::operator new?
Asked Answered
E

1

15

The documentation for the std::allocator<T>::allocate member function says in ([allocator.members]) that:

Remarks: The storage for the array is obtained by calling ​::​operator new ([new.delete]), but it is unspecified when or how often this function is called. This function starts the lifetime of the array object, but not that of any of the array elements.

I wonder why it says ::operator new and not just operator new? Does the double colon make any difference? Which other operator new could be called here, if that double colon was omitted?

Elephant answered 27/2 at 14:29 Comment(7)
https://mcmap.net/q/757833/-what-are-quot-operator-new-quot-and-quot-operator-delete-quotCassondracassoulet
@Cassondracassoulet I can understand that, in general, we sometimes need to distinguish between the global and class-specific operator new. But how is this related to std::allocator?Elephant
new is an operator, and as such is subject to the rules of ADL like other operators. By using ::operator new the ADL gets bypassed and only the global new defined by the compiler, or the global new you have replaced it with, will be used.Sklar
@Sklar I understand that. But I don't know which other possible operator new could be selected by ADL here than that global one (compiler-defined or replaced)?Elephant
Classes can overload operator new. If they did so and allocate just used new T then you would get that class overload of new instead of the global new. ::operator new stops that from happening even if the class overloads newSklar
@Sklar How can std::allocator<T>::allocate use new T? It should just allocate and not initialize any objects of type T. Or am I wrong?Elephant
@DanielLangr Sorry, should have said if they used operator new, and now that I say that I get your confusion. They would have to use T::operator new to get the class new.Sklar
F
17

Prior to LWG2818, [contents]p3 read:

Whenever a name x defined in the standard library is mentioned, the name x is assumed to be fully qualified as ::std::x, unless explicitly described otherwise. For example, if the Effects: element for library function F is described as calling library function G, the function ::std::G is meant.

So writing operator new in the specification would mean ::std::operator new, which wouldn't make sense. ::operator new correctly refers to operator new in the global namespace.

In an implementation of the standard library, there would be no difference between writing operator new and ::operator new since std::allocator<T> wouldn't define a member operator new and ADL has no effect since there is only one namespace a free operator new could be defined in.

Flagship answered 27/2 at 15:20 Comment(1)
It is exactly the explanation I was looking for. Thanks! I didn't know about this rule and learnt something new today.Elephant

© 2022 - 2024 — McMap. All rights reserved.