Andrey Surovtsev Andrey Surovtsev - 10 months ago 54
C++ Question

Why does std::stable_partition compile without an explicit namespace specification

I am working on Ubuntu with

gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2)

The following code is an example provided at entry about std::stable_partition

That's not an exact copy however, I removed the namespace scope qualifier (
) from the call to the
of the

I expect the program to not compile when I simply feed it to the g++ like that:

$ g++ -Wall -std=c++14 sp_test.cpp 

however it compiles with no errors or even warnings.

Does anyone know why?

It seems as if it has been written
using std::stable_partition
somewhere under the hood of the

I am new to C++ and g++ so I'd would also like to know whether it is an adequate question or not, i.e. should I ever bother with such (seeming) violations of the expected behaviour of the g++.

// stable_partition example
#include <iostream> // std::cout
#include <algorithm> // std::stable_partition
#include <vector> // std::vector

bool IsOdd (int i) { return (i%2)==1; }

int main () {
std::vector<int> myvector;

// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

std::vector<int>::iterator bound;
bound = stable_partition (myvector.begin(), myvector.end(), IsOdd);

// print out content:
std::cout << "odd elements:";
for (std::vector<int>::iterator it=myvector.begin(); it!=bound; ++it)
std::cout << ' ' << *it;
std::cout << '\n';

std::cout << "even elements:";
for (std::vector<int>::iterator it=bound; it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';

return 0;

Answer Source

It's because of argument-dependent lookup. Your implementation happens to define std::vector<int>::iterator inside the std namespace, therefore name lookup for stable_partition implicitly searches inside std.

This is not portable code, because std::vector<int>::iterator may be a typedef of some type that is not directly declared within std (it may be in a nested namespace, or a namespace with a reserved name, or something like that), so argument-dependent lookup will not necessarily search inside std.