很多情况下需要获得一个函数的地址
例如可以生成一个函数
参数是一个指向另一个函数的指针
//: C05:TemplateFunctionAddress.cpp {-mwcc}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Taking the address of a function generated
// from a template.
template<typename T> void f(T*) {}
void h(void (*pf)(int*)) {}
template<typename T> void g(void (*pf)(T*)) {}
int main() {
h(&f<int>); // Full type specification
h(&f); // Type deduction
g<int>(&f<int>); // Full type specification
g(&f<int>); // Type deduction
g<int>(&f); // Partial (but sufficient) specification
} ///:~
无输出
既然使用模板,所有标识就必须匹配
函数h()有一个指针参数
指针指向一个函数
指针有一个int*参数
返回值类型为void
transform算法的第4个参数作用到字符串s中的每一个字符上
这个算法把结果写回s中
将s中的每一个字符都用它的小写形式进行重写
//: C05:FailedTransform.cpp {-xo}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
using namespace std;
int main() {
string s("LOWER");
transform(s.begin(), s.end(), s.begin(), tolower);
cout << s << endl;
getchar();
} ///:~
输出
lower
即使编译器让这个程序侥幸通过
程序也是不合法的
原因是<iostream>头文件中也建造了可利用的具有两个参数的tolower()和toupper()
在一个语义明确的语境中调用tolower()
例如可以编写一个名叫strTolower()函数
放在一个不包含<iostream>的独立文件中
//: C05:StrTolower.cpp {O} {-mwcc}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include <algorithm>
#include <cctype>
#include <string>
using namespace std;
string strTolower(string s) {
transform(s.begin(), s.end(), s.begin(), tolower);
return s;
} ///:~
程序没有包含头文件<iostream>
在这种语境中
程序使用的编译器就不会引入带有两个参数的tolower()版本
当然不会产生任何问题
//: C05:Tolower.cpp {-mwcc}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
//{L} StrTolower
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
using namespace std;
string strTolower(string);
int main() {
string s("LOWER");
cout << strTolower(s) << endl;
getchar();
} ///:~
输出
lower
另一个解决办法是写一个经过封装的函数模板
用来清除地调用正确的tolower()版本
//: C05:ToLower2.cpp {-mwcc}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
using namespace std;
template<class charT> charT strTolower(charT c) {
return tolower(c); // One-arg version called
}
int main() {
string s("LOWER");
transform(s.begin(),s.end(),s.begin(),&strTolower<char>);
cout << s << endl;
getchar();
} ///:~
输出
lower
这个版本的好处
由于基础字符类型是一个模板参数
因而该模板既可以处理宽字符串
也可以处理窄字符串