2017-05-09 33 views
0

摘要时,Boost头:不明确的重载编译C++ 98的代码与C++ 11选项

我的C++代码98使用了一些Boost库和自己的一些功能(在C +现有+11)在自己的namspace中定义。它用gcc 4.8.x编译得很好。当我试着使用选项-std=c++11编译它,我得到我自己的功能call to overloaded xxx is ambiguous错误在我自己的命名空间。该函数存在于命名空间为std的C++ 11中。它看起来像升压调用头using namespace std; ...

详情:

考虑以下简单的代码:

#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; 
} 

它用gcc 4.8.5编译非常好,下面命令:g++ test.cpp -o test.exe -I /softs/boost/1.63.0/64/gcc/4.8.5/include

如果我在编译命令中添加了选项-std=c++11,则出现错误:

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) 

我没有错误,如果我删除了包含boost::math::erf函数。 我没有错误,如果我取代由caduchon::is_sortedis_sorted(但我不想影响我的所有代码)。

它真的看起来像升压的头调用using namespace std;选项-std=c++11定义的时候。

为什么?在我看来,在头文件中调用using namespace ...;是一种非常糟糕的做法......这是一个错误吗?

有一个简单的解决方案不打扰我的代码?

注:我有选择-std=c++11编译能够我的代码的特定模块中使用Boost.Process(与Boost 1.64),针对特定平台,具体的编译标志。其余的代码必须在旧的gcc(4.4.x)下编译。在动作

+3

这就是为什么你真的应该避免使用'使用命名空间任何东西;'http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-坏习惯 – NathanOliver

+0

你是对的。我不使用它。这是问题... – Caduchon

+0

@NathanOliver:即使没有使用名称空间,也可能发生这种情况。 – Jarod42

回答

3

参数-dependent_name_lookup(ADL):

x.begin()返回类型为std::vector<double>::iterator。 如果它属于std命名空间,那么

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

在命名空间std抬头了。

升压可能添加一些包括(<algorithm>)有条件地支持在其首部C++ 11层的功能。

那天正好没有任何using namespace std;

+0

你应该更清楚地说明'不使用namespace std;'。 – Yakk

+0

感谢您的解释。你有任何想法解决方法? – Caduchon

+0

完全限定呼叫:'caduchon :: is_sorted',重命名函数以避免名称冲突,或者如果它与'std :: is_sorted'相同,则移除'caduchon :: is_sorted'。 – Jarod42