C++编程思想 第2卷 第5章 深入理解模板 有关函数模板的几个问题 函数模板参数的类型推断

若一个函数模板的返回类型是一个独立的模板参数
当调用它的时候就一定要明确知道的类型
因为这时已经无法从函数参数中推断出它的类型了

//: C05:StringConv.h
// 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.
// Function templates to convert to and from strings.
#ifndef STRINGCONV_H
#define STRINGCONV_H
#include <string>
#include <sstream>

template<typename T> T fromString(const std::string& s) {
  std::istringstream is(s);
  T t;
  is >> t;
  return t;
}

template<typename T> std::string toString(const T& t) {
  std::ostringstream s;
  s << t;
  return s.str();
}
#endif // STRINGCONV_H ///:~


这些函数模板提供了std::string与任意类型之间的转换
二者分别给出了一个流类插入符和提取符

使用了包含在标准库中复数 complex 类的测试程序

//: C05:StringConvTest.cpp
// 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 <complex>
#include <iostream>
#include "StringConv.h"
using namespace std;

int main() {
  int i = 1234;
  cout << "i == \"" << toString(i) << "\"" << endl;
  float x = 567.89;
  cout << "x == \"" << toString(x) << "\"" << endl;
  complex<float> c(1.0, 2.0);
  cout << "c == \"" << toString(c) << "\"" << endl;
  cout << endl;

  i = fromString<int>(string("1234"));
  cout << "i == " << i << endl;
  x = fromString<float>(string("567.89"));
  cout << "x == " << x << endl;
  c = fromString<complex<float> >(string("(1.0,2.0)"));
  cout << "c == " << c << endl;
  getchar();
} ///:~


输出
i == "1234"
x == "567.89"
c == "(1,2)"

i == 1234
x == 567.89
c == (1,2)

在每一个fromString()的实例化调用中
都指定了模板参数
如果有一个函数模板
它的模板参数即作为参数类型又作为返回类型
一定要首先声明函数的返回类型参数

//: C05:ImplicitCast.cpp
// 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.

template<typename R, typename P>
R implicit_cast(const P& p) {
  return p;
}

int main() {
  int i = 1;
  float x = implicit_cast<float>(i);
  int j = implicit_cast<int>(x);
  //! char* p = implicit_cast<char*>(i);
} ///:~

无输出

如果将程序中靠近文件顶部的模板参数列表中的R和P交换一下
这个程序将不能通过编译
因为没有指定函数的返回类型
最后一行也是不合法的用法

可以推断出数组的维数
有一个数组初始化函数模板 init2

//: C05:ArraySize.cpp
// 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 <cstddef>
using std::size_t;

template<size_t R, size_t C, typename T>
void init1(T a[R][C]) {
  for(size_t i = 0; i < R; ++i)
    for(size_t j = 0; j < C; ++j)
      a[i][j] = T();
}

template<size_t R, size_t C, class T>
void init2(T (&a)[R][C]) {  // Reference parameter
  for(size_t i = 0; i < R; ++i)
    for(size_t j = 0; j < C; ++j)
      a[i][j] = T();
}

int main() {
  int a[10][20];
  init1<10,20>(a);  // Must specify
  init2(a);         // Sizes deduced
} ///:~

无输出

数组维数没有被作为函数参数类型的一部分进行传递
除非这个参数是指针或引用

猜你喜欢

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