no matching function for call to ‘transform

使用c++标准库transform将string转化大小写时,编译出现以下错误:

 

#include #include #include std::transform(res.begin(), res.end(), res.begin(), std::tolower);

 

no matching function for call to ‘transform(__gnu_cxx::__normal_iterator, std::allocator > >, __gnu_cxx::__normal_iterator, std::allocator > >, __gnu_cxx::__normal_iterator, std::allocator > >, )’
make: *** [CmdMessage.o] Error 1

 

在网上查到错误原因:

            在里面声明了一个C版本的函数tolower,int tolower(int); 而在中间也声明了一个函数模板:

template
charT tolower( charT c , const locale& loc );

           如果这两个头文件都同时包含到程序中来的话(C++标准头文件可能会包含另外的标准头文件。例如有的编译器在一些标准头文件中,如,会包含头文件。这样,包含可能会引入),由于这些 tolower 函数都位于同一 std 名字空间,于是形成了函数重载。这样的话,transform 函数(也是一个模板函数)的第四个参数是tolower 的时候,此时给定的 tolower 只是作为一个函数指针使用,缺乏类型推导所需要的函数参数信息,所以无法推导出函数的类型,也就无法决定使用哪一个重载函数。

 

 

 

如果想使用非模版的 tolower 函数,有多种方法可以解决:

  

transform( s.begin(), s.end(), s.begin(), (int(*)(int))tolower);

 

或者


int (*pf)( int ) = tolower; // pf 是一个函数指针,其类型已经明确。
transform( s.begin(), s.end(), s.begin(), pf );

 

或者

 

// 使用一个包装函数,避免直接使用 tolower 函数由于重载带来的问题。
int my_tolower( int c )
{
return tolower( c ); // 根据 c 的类型可以确定使用 tolower 的哪个重载函数。
}

// ...
// my_tolower 是非模版非重载函数,避免了函数重载带来的类型解析问题。


transform( s.begin(), s.end(), s.begin(), my_tolower );

 

          另外,非模板函数的 tolower 其实是来自于标准 C 库函数,因此在 C++ 标准库中它同时位于全局和 std 名字空间。既然 std 名字空间内 tolower 函数有可能形成函数重载,但是在全局名字空间中的 tolower 函数却只有一个,所以也可以直接使用全局名字空间中的 tolower:

transform( s.begin(), s.end(), s.begin(), ::tolower);

 

 

你可能感兴趣的:(Linux,C/C++)