模糊的C++编译器错误

8 c++ namespaces compiler-errors ambiguous

以下代码无法编译.该错误似乎是对合并例程的某种模糊调用.我的理解是STL有一个在std命名空间中找到的合并例程,但据我所知,下面代码中的名称merge应该是唯一的.

如果我将merge重命名为xmerge,一切正常.问题是什么?冲突的名称来自何处?

http://codepad.org/uAKciGy5

#include <iostream>
#include <iterator>
#include <vector>

template<typename InputIterator1,
         typename InputIterator2,
         typename OutputIterator>
void merge(const InputIterator1 begin1, const InputIterator1 end1,
           const InputIterator2 begin2, const InputIterator2 end2,
           OutputIterator out)
{
   InputIterator1 itr1 = begin1;
   InputIterator2 itr2 = begin2;
   while ((itr1 != end1) && (itr2 != end2))
   {
      if (*itr1 < *itr2)
         *out = *itr1, ++itr1;
      else
         *out = *itr2, ++itr2;
      ++out;
   }
   while (itr1 != end1) *out++ = *itr1++;
   while (itr2 != end2) *out++ = *itr2++;
}

int main()
{
   std::vector<int> l1;
   std::vector<int> l2;
   std::vector<int> merged_list;

   merge(l1.begin(),l1.end(),
         l2.begin(),l2.end(),
         std::back_inserter(merged_list));

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

Nav*_*een 17

编译器在你的merge函数和std::merge定义的函数之间变得混乱algorithm.使用::merge消除这种不确定性.此调用不明确,因为编译器使用Argument Dependendent Lookup在使用非限定函数名时搜索函数.

  • @Reyzooti:问题是Argument Dependent Lookup意味着由于传递给函数调用的类型是在`std`中定义的,因此`std`命名空间进入搜索空间.基本上,这使您能够在`std`命名空间之外编写`std :: string("Hi")+ std :: string("there")`.字符串的`operator +`是在`std`中定义的,但你肯定希望代码能够工作而不必编写`std :: operator +(str1,str2)`或`str1.operator +(str2)`,具体取决于运算符是定义的,我不太关心. (7认同)
  • @Reyzooti:是的,标准库的`merge`版本在`std`命名空间中 - 但ADL仍然使它被认为是候选者,因为该函数的参数来自`std`命名空间(有关详细信息) ADL的工作原理见维基百科文章). (5认同)
  • @Reyzooti:我几乎肯定我在这方面没有错.如果在全局命名空间中声明`merge`的标准库头文件,它可能被认为是一个问题,但问题是ADL将从参数的命名空间带来标识符,所以即使`std :: merge`是只在`std`标题内声明,因为参数,它将在查找中被考虑.我在第一篇评论中写的简单案例应该证明这一点.否则试试这个:`namespace X {struct test {}; void foo(test const&){}}; int main(){X :: test t; 脚丫子); }` (5认同)