C++编程思想 第2卷 第5章 深入理解模板 有关函数模板的几个问题 以一个已生成的函数模板地址作为参数

很多情况下需要获得一个函数的地址
例如可以生成一个函数
参数是一个指向另一个函数的指针

//: 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

这个版本的好处
由于基础字符类型是一个模板参数
因而该模板既可以处理宽字符串
也可以处理窄字符串

猜你喜欢

转载自blog.csdn.net/eyetired/article/details/82084364