0

Abstract :

My C++98 code uses some boost libraries and some own functions (existing in C++11) defined in a own namspace. It compiles very well with gcc 4.8.x. When I try to compile it with option -std=c++11, I get a call to overloaded xxx is ambiguous error on my own function in my own namespace. This function exists in C++11 in namespace std. It looks like boost calls using namespace std; in a header...

Details :

Consider the following simple code :

#include <vector>
#include <iostream>
#include <boost/math/special_functions/erf.hpp>
namespace caduchon
{
    template <typename Iterator>
    bool is_sorted(Iterator begin, Iterator end)
    {
        if(begin == end) return true;
        for(Iterator it = begin, prev = it++; it != end; prev = it++)
            if(*it < *prev) return false;
        return true;
    }
}

using namespace caduchon;
int main()
{
    std::vector<double> x(3);
    x[0] = 10.0; x[1] = 13.9; x[2] = 21.3;
    std::cout << "Is x sorted ? " << is_sorted(x.begin(), x.end()) << std::endl;
    // Imagine here a call to boost::math::erf(double)
    return 0;
}

It compiles very well with gcc 4.8.5 with the following command : g++ test.cpp -o test.exe -I /softs/boost/1.63.0/64/gcc/4.8.5/include

I have an error if I add the option -std=c++11 in the compilation command :

g++ test.cpp -o test.exe -I /softs/boost/1.63.0/64/gcc/4.8.5/include -std=c++11
test.cpp: In function ‘int main()’:
test.cpp:28:61: error: call of overloaded ‘is_sorted(std::vector<double>::iterator, std::vector<double>::iterator)’ is ambiguous
  std::cout << "is sorted ? " << is_sorted(x.begin(), x.end()) << std::endl;
                                                             ^
test.cpp:28:61: note: candidates are:
test.cpp:9:7: note: bool caduchon::is_sorted(Iterator, Iterator) [with Iterator = __gnu_cxx::__normal_iterator<double*, std::vector<double> >]
  bool is_sorted(Iterator begin, Iterator end)
       ^
In file included from /usr/include/c++/4.8/algorithm:62:0,
                 from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/tools/config.hpp:18,
                 from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/tools/promotion.hpp:26,
                 from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/special_functions/detail/round_fwd.hpp:12,
                 from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/special_functions/math_fwd.hpp:26,
                 from /softs/boost/1.63.0/64/gcc/4.8.5/include/boost/math/special_functions/erf.hpp:13,
                 from test.cpp:3:
/usr/include/c++/4.8/bits/stl_algo.h:3952:5: note: bool std::is_sorted(_FIter, _FIter) [with _FIter = __gnu_cxx::__normal_iterator<double*, std::vector<double> >]
     is_sorted(_ForwardIterator __first, _ForwardIterator __last)

I don't have the error if I remove the inclusion for boost::math::erf function. I don't have the error if I replace is_sorted by caduchon::is_sorted (but I don't want to impact all my code).

It realy looks like a header of boost calls using namespace std; when option -std=c++11 is defined.

Why ? In my opinion, it's a very bad practice to call using namespace ...; in a header... Is it a bug ?

Is there a simple solution not intrusive for my code ?

Note : I have to compile with option -std=c++11 to be able to use Boost.Process (from Boost 1.64) in a specific module of my code, for a specific platform, with specific compilation flags. The rest of the code must compile under old gcc (4.4.x).

Caduchon
  • 4,574
  • 4
  • 26
  • 67

1 Answers1

3

Argument-dependent_name_lookup (ADL) in action:

x.begin() return type is std::vector<double>::iterator. if it belongs to std namespace, then

is_sorted(x.begin(), x.end())

is look up in namespace std too.

Boost might add some include (<algorithm>) conditionally to support c++11 features in its header.

That happens without any using namespace std;

Jarod42
  • 203,559
  • 14
  • 181
  • 302