对std / boost移动的模糊调用

时间:2015-06-30 23:37:10

标签: c++ boost

遇到这个无法编译的代码:

#include <boost/move/utility.hpp>
#include <utility>
#include <deque>
#include <map>
#include <vector>
#include <boost/date_time/posix_time/posix_time_types.hpp>

using namespace std;

int main() {
    typedef std::pair<int, std::deque<int>> FirstPair;
    typedef std::vector<FirstPair> VectorFirstPair;
    typedef std::pair<boost::posix_time::time_duration, VectorFirstPair> SecondPair;
    typedef std::map<boost::posix_time::time_duration, SecondPair> Map;
    Map mapInstance;
    SecondPair newElement = make_pair(boost::posix_time::not_a_date_time, VectorFirstPair());
    mapInstance.insert(make_pair(boost::posix_time::seconds(10), move(newElement))).first;
}

使用boost 1.55(不在boost 1.54上)时,gcc 4.8.2失败并出现以下错误(ideone here):

test.cpp: In function ‘int main()’:
test.cpp:17:81: error: call of overloaded ‘move(SecondPair&)’ is ambiguous
     mapInstance.insert(make_pair(boost::posix_time::seconds(10), move(newElement))).first;
                                                                                 ^
test.cpp:17:81: note: candidates are:
In file included from /usr/include/c++/4.8/bits/stl_pair.h:59:0,
                 from /usr/include/c++/4.8/utility:70,
                 from /usr/include/boost/config/no_tr1/utility.hpp:21,
                 from /usr/include/boost/config/select_stdlib_config.hpp:37,
                 from /usr/include/boost/config.hpp:40,
                 from /usr/include/boost/move/detail/config_begin.hpp:10,
                 from /usr/include/boost/move/utility.hpp:17,
                 from test.cpp:1:
/usr/include/c++/4.8/bits/move.h:101:5: note: constexpr typename std::remove_reference< <template-parameter-1-1> >::type&& std::move(_Tp&&) [with _Tp = std::pair<boost::posix_time::time_duration, std::vector<std::pair<int, std::deque<int> > > >&; typename std::remove_reference< <template-parameter-1-1> >::type = std::pair<boost::posix_time::time_duration, std::vector<std::pair<int, std::deque<int> > > >]
     move(_Tp&& __t) noexcept
     ^
In file included from test.cpp:1:0:
/usr/include/boost/move/utility.hpp:138:55: note: typename boost::remove_reference<T>::type&& boost::move(T&&) [with T = std::pair<boost::posix_time::time_duration, std::vector<std::pair<int, std::deque<int> > > >&; typename boost::remove_reference<T>::type = std::pair<boost::posix_time::time_duration, std::vector<std::pair<int, std::deque<int> > > >]
          inline typename remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT

这不应该编译吗? using namespace条款不应该明确这个吗?为什么编译器在这里选择boost::move作为可行的候选者?

请注意,如果我删除定义类型中的boost类型(例如将其替换为int),则不会导致任何错误。

2 个答案:

答案 0 :(得分:4)

这是因为ADL - 参数相关的查找(请参阅此answer,这也与增强相关)。

问题在于考虑名称空间boost是因为:

  

§3.4.2依赖于参数的名称查找

     
      
  1. ...名称空间和类的集合完全由函数参数的类型(以及任何模板模板参数的名称空间)决定。 ...
  2.   

因此,因为某些与boost相关的类型是std::pair的模板参数,所以也会考虑boost::move。 (imho它不应该因为我无法弄清楚如何围绕这种模糊性进行编程)。

答案 1 :(得分:1)

作为在任何地方明确限定std::move的替代方法,您可以定义BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE,只需将boost::move别名为std::move。有了这个,your example compiles successfully