什么在这里与cctype?

时间:2011-03-23 18:18:56

标签: c++ namespaces std

令我惊讶的是,以下代码编译:

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <cctype>

int main() {
   std::string s="nawaz";
   std::string S;
   std::transform(s.begin(),s.end(), std::back_inserter(S), ::toupper);
   std::cout << S ;
}

由于我认为应该在::toupper命名空间中的std,我原以为它会失败。快速检查cctype显示它是,但它是从根namesescece导入(神秘解决那里)。

namespace std
{
  // Other similar `using` deleted for brevity.
  using ::toupper;
}

所以第一个问题已经解决,但如果我也改变了上面的transform()行:

std::transform(s.begin(),s.end(), std::back_inserter(S), std::toupper);

我现在希望现在也可以编译。但是我收到编译器错误:

  

kk.cpp:12:错误:没有匹配函数来调用`transform(__ gnu_cxx :: __ normal_iterator&lt; char *,std :: basic_string&lt; char,std :: char_traits&lt; char&gt ;,std :: allocator&lt; char&gt; &gt;&gt;,__ gn_cxx :: __ normal_iterator&lt; char *,std :: basic_string&lt; char,std :: cha   r_traits&lt; char&gt ;,std :: allocator&lt; char&gt; &GT; &gt;,std :: back_insert_iterator&lt; std :: basic_string&lt; char,std :: char_traits&lt; char&gt ;,std :: allocator&lt; char&gt; &GT; &gt;,&lt; 未解决的重载功能类型 &gt;)'

手动编辑也解决了这个问题:

kk.cpp:12: error: no matching function for call to
         `transform(iterator<std::string>,
                    iterator<std::string>,
                    std::back_insert_iterator<std::string>,
                    <unresolved overloaded function type>)'

我错过了什么?

2 个答案:

答案 0 :(得分:11)

它不起作用,因为std::toupper有重载。您可以通过强制转换为所需的函数重载来修复它:

std::transform(s.begin(),s.end(), std::back_inserter(S),
                (int(&)(int))std::toupper);

答案 1 :(得分:4)

您错过了C ++ toupper中添加了新的<locale>函数,这可能是您的其他标题之一隐式包含的。因此,在std::命名空间中有多个重载,而在全局命名空间中只有该函数的旧C版本。

那说看起来似乎g ++应该能够推断出正确的过载。