Historically, it seems that there was not much thought about name resolution. std::swap was designed as a configuration point, but it was also launched as a function that could be called in the general code for data exchange. Therefore, if std::swap did not work or was too slow, then it might have to overload it even if an excellent swap was found with ADL. This design cannot be changed without breaking or changing the meaning of existing code. Now there have been cases when the committee gladly decided to change the value of the existing code for the sake of performance, for example, the semantics of implicit movement (for example, when transmitting temporary values ββby value or RVO, where elite is not implemented). So this is not entirely clear. However, changing std::swap from a configuration point to a name resolution wrapper with all existing existing std::swap overloads is questionable. This can lead to catastrophic errors in poorly written legacy code.
Another important reason is IMO, that you cannot move this idiom into the std , while maintaining your commonality. For example:.
namespace A { struct X{}; } namespace B { using std::swap; void swap(A::X&, A::X&); template<typename T> void reverse(T (&ts)[4]) { swap(ts[0], ts[3]); swap(ts[1], ts[2]); } void silly(A::X (&xs)[4]) { reverse(xs); } }
Here silly ends with B::swap . The reason for this is that std::swap (via using ) and B::swap displayed with the same priority, but the latter is better. Now you can argue that this is a stupid example, so here is a little more, which is a bit far-fetched:
namespace types { } namespace algorithms { } template<typename T> void reverse(T (&ts)[4]) { using std::swap; using algorithms::swap; swap(ts[0], ts[3]); swap(ts[1], ts[2]); }
This will use the swap function from algorithms if it is better than any overload of std::swap , but algorithms::swap will not be found by ADL, so the search cannot happen inside std::swap , in the general case. An arbitrary number of namespaces can be involved here.
Arne vogel
source share