C++ STL transform 函数说明

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ STL transform 函数说明相关的知识,希望对你有一定的参考价值。

参考技术A 简而言之, transform 是用来做转换的。
转换有两种:一元转换和二元转换。

一元转换是对容器给定范围内的每个元素做某种一元运算后放在另一个容器里。只涉及一个参与转换运算的容器。
有4个参数,前2个指定要转换的容器的起止范围,第3个参数是结果存放容器的起始位置,第4个参数是一元运算。
函数签名是:

二元转换是对两个容器给定范围内的每个元素做二元运算后放在另一个容器里。涉及两个参与转换运算容器。
有5个参数,前2个指定参与转换的第1个容器的起止范围,第3个参数是转换的第2个容器的起始位置,
第4个参数是结果存放容器的起始位置,第5个参数是二元运算。
函数签名是:

#include <algorithm>

结果:

这是一元转换。

结果:

这是二元转换。

http://www.cplusplus.com/reference/algorithm/transform/
https://zh.cppreference.com/w/cpp/algorithm/transform

[转]STL transform算法中使用toupper函数

原文转自 http://blog.csdn.net/justin12zhu/article/details/5649236  

今天需要实现一个把小写字母转换为大写字母的函数,由于传入的参数是STL中的string类,所以第一想法就是用transform算法来实现这功能,但是报错了。回家之后写了下面一个测试代码来看看到底错在哪里和怎么解决。

#include <iostream>
#include <algorithm>
#include <cctype>

using namespace std;
 
int main(int argc, char *argv[])
{
    string s("hello world");
    transform(s.begin(), s.end(), s.begin(), toupper);
    cout<<s<<endl;
    return 0;   
}

下面是g++的报错信息:

no matching function for call to `transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char,std::char_traits<char>,std::allocator<char>>>,__gnu_cxx::__normal_iterator<char*,std::basic_string<char,std::char_traits<char>,std::allocator<char>>>,__gnu_cxx::__normal_iterator<char*,std::basic_string<char,std::char_traits<char>, std::allocator<char> > >, <unknown type>)‘

从上面红的部分可以看出,touppe函数被认为是未知类型的函数了。但是我另外把toupper函数独立抽出来测试的时候编译是通过的,也就是说这个函数是没问题的,那么到底问题在哪呢?

       在网上游荡一圈之后,终于找到了原因:

       标准库重载了一个touppe函数,而GCC完全由C库去提供重载,而glibc做不到这一点,所以在编译的时候g++就认为这个函数有歧义了。下面就是在标准库中toupper函数的两种形式:

int std :: toupper ( int ); // from <cctype>
template < class chart >
char T std :: toupper ( char T , const locale &);  // from <locale>

    问题找出来了,但是总要有解决的方法。既然报错是因为有歧义,所以只要把歧义消除便可。

1、通过介入包装函数

这是最简单的办法,因为包装函数只有一个,只要在包装函数中指明要使用的函数,歧义自然就没了,以toupper为例,我们可以使用下面这样的一个包装函数:

int toUpper( int c )
{
       return toupper( c ) ;
}

2、强制转化:将toupper转换为一个返回值为int,参数只有一个int的函数指针:

std::transform(s.begin(), s.end(), s.begin(), (int(*)(int)) toupper);

3、GCC中将toupper实现为一个宏而不是函数,而在全局命名空间中有实现的函数(而不是宏),所以我们明确命名空间,这并不是总奏效,但是在我的g++环境中没有问题:

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

 

以上是关于C++ STL transform 函数说明的主要内容,如果未能解决你的问题,请参考以下文章

求大神以这个C++代码为例对STL标准模板库的容器,迭代器,算法和函数对象进行分析

C++中STL常用算法

[转]STL transform算法中使用toupper函数

C++ STL 之 常用算法

新手用C++写了个泛型堆,效率竟比STL的更快?

C++从青铜到王者第七篇:STL之string类的初识