1

I figured out that one can use a lot of ( perhaps all the) functions of the algorithm library with or without namespace std: e.g. when algorithm is imported:

#include <algorithm>

std::unique and unique seem to be equivalent. Here is an example:

#include <iostream>
#include <vector>
#include <algorithm>


int main () {
    std::vector<int> v = {10,20,20,20,30,30,20,20,10};
    std::vector<int>::iterator it;

    it = std::unique (v.begin(), v.end());
    for (it=v.begin(); it!=v.end(); ++it)
        std::cout << ' ' << *it;
        std::cout << '\n';

    it = unique (v.begin(), v.end());
    for (it=v.begin(); it!=v.end(); ++it)
        std::cout << ' ' << *it;
        std::cout << '\n';
}

The output:

10 20 30 20 10 30 20 20 10
10 20 30 20 10 30 20 20 10

1) Are they the same functions?

2) What is the mechanism that enables using these functions regardless the use of the std namespace? I looked up the source code: https://github.com/gcc-mirror/gcc/blob/d9375e490072d1aae73a93949aa158fcd2a27018/libstdc%2B%2B-v3/include/bits/stl_algo.h

and

https://github.com/gcc-mirror/gcc/blob/d9375e490072d1aae73a93949aa158fcd2a27018/libstdc%2B%2B-v3/include/std/algorithm

but I have still no idea about how that works.

Thank you in advance.

moth
  • 345
  • 1
  • 13

1 Answers1

5

As mentioned in the comments unique without std:: works because of argument-dependent lookup.

v.begin() and v.end() return std::vector<int>::iterator which is some iterator for the std::vector<int>. This could be any type satisfying the iterator requirements. It could be a simple pointer to int or more likely a class with overloaded operators.

If the iterator is a class type then argument-dependent lookup will search for unique in that class and the classes enclosing namespace scope. If that enclosing namespace scope happens to be ::std, then ::std::unique will be found and used.

There is no guarantee that this works. It depends on the standard library implementation whether it will or not.

For example with std::array instead of std::vector it works on MSVC, but not on Clang (with libc++) or GCC (with libstdc++), because the latter two just use int* as iterator, see https://godbolt.org/z/Ysu2-d.

You should always refer to std::unique with its qualified name.

walnut
  • 21,629
  • 4
  • 23
  • 59