#introduction
本章关注cpp编译对代码的影响以及一些编译相关的技巧。
template 方法
综述
查看cplusplus中的定义:
http://www.cplusplus.com/doc/oldtutorial/templates/
-
功能:
模板方法,定义广义类型 -
declaration:
template <class identifier> function_declaration;
template <typename identifier> function_declaration;
- defintions:
template <class myType>
myType GetMax (myType a, myType b) {
return (a>b?a:b);
}
- examples:
// function template
#include <iostream>
using namespace std;
template <class T>
T GetMax (T a, T b) {
T result;
result = (a>b)? a : b;
return (result);
}
int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax<int>(i,j);
n=GetMax<long>(l,m);
cout << k << endl;
cout << n << endl;
return 0;
}
- 疑问
1)模板方法的实现原理?
通过在编译时确定数据类型,然后替换T的类型。所以如果确定了输入类型,不需要在调用函数时再指定类型GetMax < int >, 在因为在GetMax时,编译器已经指定了template的类型,所以不需要在申明result的类型。
2)如果函数的形参可能是不同的类型,在使用的时候,也同样可以指明类型,也可以不指明类型,
template <class T, class U>
T GetMin (T a, U b) {
return (a<b?a:b);
}
3)如果是类中的成员变量要使用template方法
// class templates
#include <iostream>
using namespace std;
template <class T>
class mypair {
T a, b;
public:
mypair (T first, T second)
{a=first; b=second;}
T getmax ();
};
template <class T>
T mypair<T>::getmax ()
{
T retval;
retval = a>b? a : b;
return retval;
}
int main () {
mypair <int> myobject (100, 75);
cout << myobject.getmax();
return 0;
}
注意类模板和普通模板函数的区别,函数定义时需要用mypair< T >, 同样还需要带上template < class T>
- 类模板中针对特殊的数据类型做一些特殊的定义
// template specialization
#include <iostream>
using namespace std;
// class template:
template <class T>
class mycontainer {
T element;
public:
mycontainer (T arg) {element=arg;}
T increase () {return ++element;}
};
// class template specialization:
template <> //注意这里不需要再用class T
class mycontainer <char> {
char element;
public:
mycontainer (char arg) {element=arg;}
char uppercase ()
{
if ((element>='a')&&(element<='z'))
element+='A'-'a';
return element;
}
};
int main () {
mycontainer<int> myint (7);
mycontainer<char> mychar ('j');
cout << myint.increase() << endl;
cout << mychar.uppercase() << endl;
return 0;
}
- 既然模板方法原理是通过编译器确定数据结构,那么可否template可否使用特定的类型,让一些数据在编译的时候才确定内存情况
例如数组的初始化
// sequence template
#include <iostream>
using namespace std;
template <class T, int N>
class mysequence {
T memblock [N];
public:
void setmember (int x, T value);
T getmember (int x);
};
template <class T, int N>
void mysequence<T,N>::setmember (int x, T value) {
memblock[x]=value;
}
template <class T, int N>
T mysequence<T,N>::getmember (int x) {
return memblock[x];
}
int main () {
mysequence <int,5> myints;
mysequence <double,5> myfloats;
myints.setmember (0,100);
myfloats.setmember (3,3.1416);
cout << myints.getmember(0) << '\n';
cout << myfloats.getmember(3) << '\n';
return 0;
}
- 如果是结构体使用template,要怎么办?
// in xx.h
template <typename T>
struct LegControllerCommand {
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
LegControllerCommand() { zero(); }
void zero();
Vec3<T> tauFeedForward, forceFeedForward, qDes, qdDes, pDes, vDes;
Mat3<T> kpCartesian, kdCartesian, kpJoint, kdJoint;
};
- 如果想限定template的类型,要如何处理?
- 限制函数
template void computeLegJacobianAndPosition<double>(Quadruped<double>& quad,
Vec3<double>& q,
Mat3<double>* J,
Vec3<double>* p, int leg);
template void computeLegJacobianAndPosition<float>(Quadruped<float>& quad,
Vec3<float>& q,
Mat3<float>* J,
Vec3<float>* p, int leg);
- 限制结构体或者类
// in xx.cpp:是否可以不这么做
template struct LegControllerCommand<double>;
template struct LegControllerCommand<float>;
template struct LegControllerData<double>;
template struct LegControllerData<float>;
template class LegController<double>;
template class LegController<float>;
References
实例代码来源于:
1.http://www.cplusplus.com/doc/oldtutorial/templates/
2.https://github.com/mit-biomimetics/Cheetah-Software