在全局命名空间中默认包含equal()吗?

时间:2014-03-01 13:23:03

标签: c++

这是关于C ++中默认全局命名空间的问题。我有以下代码使用g ++ clang-500.2.79编译和运行。

#include <string>
#include <iostream>

using std::string;
using std::endl; 
using std::cout;

bool is_palindrome(const string& str){
    return equal(str.begin(), str.end(), str.rbegin());
}

int main(){

    cout << "Hello is a palindrome: " << is_palindrome("Hello") << endl;
    cout << "madam is a palindrome: " << is_palindrome("madam") << endl;

    return 0;
}

我的问题是,为什么这段代码编译正确?我忘了将#include <algorithm>using std::equal放在我文件的开头。所以预期的行为是让编译器抱怨。

http://en.cppreference.com/w/cpp/algorithm/equal处的示例确认我应该使用std::equal

为了进一步调查此问题,我尝试跟踪完全正在调用哪个版本的equal()函数。作为C ++的相对新手我也不知道如何做到这一点。我试过了,

cout << "The function is: " << equal << endl;

这产生了编译器错误,其中包含一些有趣的信息:

/usr/include/c++/4.2.1/bits/stl_algobase.h:771:5: 
note: 'std::equal' declared here

尽我所能,我找不到有关stl_algobase的信息(或者更可能的是,我很可能不理解我发现的内容)。 stl_algobase是一组自动包含在全局命名空间中的函数吗?

另外一个问题是:在C ++中处理潜在的重载或模板函数时,跟踪(代码或其他)函数的正确方法是什么?

1 个答案:

答案 0 :(得分:5)

equal位于std命名空间中。你看到的是argument dependent lookup(ADL)。由于参数位于std中,因此equal的名称查找也会考虑该命名空间。

这是一个简化的例子:

namespace foo
{
  struct Bar {};
}

namespace foo
{
  void bar(const Bar&) {}
  void bar(int) {}
}

int main()
{
  foo::Bar b;
  foo::bar(b);  // OK
  bar(b);       // ADL, OK
  foo::bar(42); // OK
  bar(42);      // No ADL: error: 'bar' was not declared in this scope
}