遇到无法编译的代码:
#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 的 gcc 4.8.2 上失败(不是在 boost 1.54 上)并出现以下错误(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
替换它们),这不会导致任何错误。
最佳答案
这是因为 ADL - 参数依赖查找(请参阅此 answer,它也与 boost 相关)。
问题是命名空间 boost
被认为是因为:
§ 3.4.2 Argument-dependent name lookup
- ... The sets of namespaces and classes is determined entirely by the types of the function arguments (and the namespace of any template template argument). ...
因此,因为某些与 boost 相关的类型是 std::pair
的模板参数,所以也考虑了 boost::move
。 (恕我直言,这不应该,因为我无法弄清楚如何围绕这种歧义进行编程)。
关于c++ - 对 std/boost 移动的模糊调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31150290/