Search code examples
c++stdargument-dependent-lookupqualified-nameunqualified-name

Which functions in standard C++ library should not be prefixed with std:: when used?


When I program in C++, instead of writing using namespace std;, I generally tend to use std:: prefixed components like std::cout, std::cin etc. But then I came across ADL and why you should use using std::swap;.

Many components of the standard library (within std) call swap in an unqualified manner to allow custom overloads for non-fundamental types to be called instead of this generic version: Custom overloads of swap declared in the same namespace as the type for which they are provided get selected through argument-dependent lookup over this generic version.

But in all sources about ADL, they only mention std::swap. Are there any other functions like this that I have to be beware of when using? Or for all other functions should I use fully qualified name? Or should I use unqualified name for every function in std::?

EDIT: (I wasn't clear when phrasing my initial question. Here is what I exactly intended when I was writing the question.)

Is there any other function in C++ standard libraries that is a popular candidate for ADL based customization much like std::swap, so that when I use them, I have to be cautious to use using std::foo; foo(); form instead of invoking std::foo(); directly?


Solution

  • Suppose you write a library that works with user supplied types. Then you might want to provide a default implementation to foo a bar. But at the same time you want to enable the user to provide their custom implementation because they might know better how to foo their custom bar.

    Thats exactly what happens in the standard library with std::swap. The code that relies on ADL is inside libraries, it works with custom types, types it doesn't know until instantiated. And it can provide a default std::swap but at the same time allows the user to provide their own implementation.

    In your user-code, when you know the type, then typically you want to know what function is called. Typically you do know if you want to call my::swap or std::swap and you do not need ADL to choose.

    That being said, if you have to ask this quesiton then the answer is: Do not make use of ADL. (I know "If you have to ask.." is somewhat silly, but sometimes is applies just too well). Even in library code you do not always want to enable ADL, or allow it as customization. Even if you do write generic code, there might be situations where you need your way to foo a bar without allowing the user to customize it. It really depends.

    Short answer: If you want to call std::swap then call std::swap. If you want to call my::swap then call my::swap. If you want to make use of ADL you will know what to do.


    PS: There are more examples of ADL that you know but might not be aware of. You almost never use the std:: prefix when you call an operator overload for example. For example std::string operator+(const std::string&,const std::string&). You could write

     std::string a,b;
     auto c = std::operator+(a,b);
    

    but you don't. You are used to write

     auto c = a + b;
    

    And this only works due to ADL.


    PPS: Even for std::swap its not right that it "should not be prefixed with std::". As outlined above, sometimes you do want to make use of ADL and sometimes you don't. That decision is not per function, but per use case. If you write code that swaps two objects and for some reason you want to call std::swap and nothing else, then you call std::swap. If you want to make use of ADL then you make use of ADL.