若一个函数模板的返回类型是一个独立的模板参数
当调用它的时候就一定要明确知道的类型
因为这时已经无法从函数参数中推断出它的类型了
//: 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
} ///:~
无输出
数组维数没有被作为函数参数类型的一部分进行传递
除非这个参数是指针或引用