Seb*_*ian 7 c++ templates visual-c++ argument-dependent-lookup
我几次被这个问题所困扰,所以我的同事也是如此.编译时
#include <deque>
#include <boost/algorithm/string/find.hpp>
#include <boost/operators.hpp>
template< class Rng, class T >
typename boost::range_iterator<Rng>::type find( Rng& rng, T const& t ) {
return std::find( boost::begin(rng), boost::end(rng), t );
}
struct STest {
bool operator==(STest const& test) const { return true; }
};
struct STest2 : boost::equality_comparable<STest2> {
bool operator==(STest2 const& test) const { return true; }
};
void main() {
std::deque<STest> deq;
find( deq, STest() ); // works
find( deq, STest2() ); // C2668: 'find' : ambiguous call to overloaded function
}
Run Code Online (Sandbox Code Playgroud)
...编译第二个查找时,VS9编译器失败.这是因为STest2从boost命名空间中定义的类型继承,触发编译器尝试找到的ADL boost::algorithm::find(RangeT& Input, const FinderT& Finder).
一个明显的解决方案是将调用前缀为find(…)" ::",但为什么这是必要的?全局命名空间中存在完全有效的匹配,那么为什么要调用Argument-Dependent Lookup?任何人都可以解释这里的理由吗?
ADL不是在"正常"重载决策失败时使用的回退机制,ADL找到的函数与正常查找找到的函数一样可行.
如果ADL是一个后备解决方案,那么即使有另一个功能更好匹配但只能通过ADL可见,你可能很容易陷入陷阱.在(例如)运算符重载的情况下,这似乎特别奇怪.您不希望通过operator==for类型比较两个对象,当operator==适当的命名空间中存在完美的优点时,它们可以隐式转换为.