【问题标题】:Ambiguous overloading due to Boost headers when compiling C++98 code with C++11 option使用 C++11 选项编译 C++98 代码时,由于 Boost 标头导致的模棱两可的重载
【发布时间】:2017-05-09 11:59:24
【问题描述】:

摘要:

我的 C++98 代码使用了一些在自己的 namspace 中定义的 boost 库和一些自己的函数(存在于 C++11 中)。它可以很好地与 gcc 4.8.x 一起编译。当我尝试使用选项 -std=c++11 编译它时,我在自己的命名空间中的自己的函数上收到 call to overloaded xxx is ambiguous 错误。此函数存在于命名空间std 中的C++11 中。看起来像在标题中的 boost 调用 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 函数的包含,我没有错误。 如果我将is_sorted 替换为caduchon::is_sorted,则不会出现错误(但我不想影响我的所有代码)。

它看起来像升值调用的标题using namespace std;定义了选项-std=c++11

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

是否有一个简单的解决方案不会干扰我的代码?

注意:我必须使用选项 -std=c++11 进行编译才能在我的代码的特定模块中使用 Boost.Process(来自 Boost 1.64),用于具有特定编译标志的特定平台。其余代码必须在旧 gcc (4.4.x) 下编译。

【问题讨论】:

  • 这就是为什么你真的应该避免使用using namespace anything;stackoverflow.com/questions/1452721/…
  • 你是对的。我不使用它。问题来了……
  • @NathanOliver:即使没有using namespace,也会发生这种情况。

标签: c++ c++11 boost namespaces c++98


【解决方案1】:

Argument-dependent_name_lookup (ADL) 在行动:

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

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

也在命名空间std中查找。

Boost 可能有条件地添加一些包含 (&lt;algorithm&gt;) 以在其标头中支持 c++11 功能。

在没有任何using namespace std; 的情况下发生这种情况

【讨论】:

  • 你应该更明确一点,using namespace std; 没有参与。
  • 感谢您的解释。您有任何解决方法的想法吗?
  • 完全限定调用:caduchon::is_sorted,重命名函数以避免名称冲突,或者删除 caduchon::is_sorted,如果它与 std::is_sorted 做同样的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 2016-03-14
  • 1970-01-01
相关资源
最近更新 更多