寻找C++实用的内联模板函数,纪念!
《Effective C++》条款02指出:你可以获得宏带来的效率以及一般函数的所有可预料行为和类型安全性(type safety)——只要你写出template inline函数。
那么,有哪些template inline值得我们在实际工程中运用呢?
希望借集体的力量,能收集到大量实用的内联函数模板函数。
这是目前我暂时能想到的,抛砖引玉,请大家不吝赐教!
template<typename T>inline void SafeDelete(T*& p){ delete p; p = 0; }template<typename T>inline void SafeDeleteArray(T*& p){ delete[] p; p = 0; }template <typename T> inline void UnusedVar(const T&){}template <typename T> inline size_t CountOf(const T& array){ UnusedVar(array); return sizeof(array) / sizeof(array[0]); }template <typename T> inline const T& Max(const T& a, const T& b){ return a > b ? a : b; }template <typename T> inline const T& Min(const T& a, const T& b){ return a < b ? a : b; }template <typename T> inline void Swap(T& a, T& b){ T t(a); a = b; b = t; }
template<class T, size_t N>inline size_t CountOf(const T(&)[N]){ return N;}
[解决办法]
//判断参数类型是否是无符号类型,当然只限于有序类型template<class T>inline bool IsUnsigned(T){ return ((T)-1 > 0);}
[解决办法]
//按内存方式强制类型转换,如将type (CLS::*pf)(type par)强制转换为void *: void *p = GetCast<void *>(pf);template<class DEST, class SRC>DEST GetCast(const SRC& src){ union { SRC src; DEST dest; }myunion = {src}; return myunion.dest;}
[解决办法]
//注意:请不要用于指针之间的转换,特别是BSTRtemplate<typename lType, typename rType>lType TranslateType(rType& rValue, IsDiff& isDiff){ stringstream is; lType lValue; is << rValue; is >> lValue; return lValue;};
[解决办法]
[解决办法]
template <typename T > struct is_a_ptr { enum{ yes = FALSE }; }; template <typename T > struct is_a_ptr <T* > { enum{ yes = TRUE }; }; template <typename T>inline void UnusedVar(const T&){ if(is_a_ptr<T>::yes) throw std:: invalid_argument("Not a array!");}template <typename T>inline size_t CountOf(const T& array){ UnusedVar(array); return sizeof(array) / sizeof(array[0]);}///////////////////////////int main(){ try { int a[10]; int b[11][12]; int *c; cout<<CountOf(a)<<'\n'; cout<<CountOf(b)<<'\n'; cout<<CountOf(c)<<'\n'; }catch(const std::exception& e) { cout<<e.what()<<'\n'; } system("pause"); return EXIT_SUCCESS;}
[解决办法]
看一下,重点是接分~!
[解决办法]
#ifndef __SINGLE_H__#define __SINGLE_H__#include <new>template <class T> class TSingle{public: inline static T* Create() { if (!spT_) { spT_ = new(&sMemory_) T; } return spT_; } inline static T* Instance() { return spT_; } inline static void Destroy() { if (spT_) { spT_->~T(); spT_ = 0; } }private: typedef union { char t_[sizeof(T)]; short int shortInt_; int int_; long int longInt_; float float_; double double_; long double longDouble_; }UNMaxAlign; static UNMaxAlign sMemory_; static T* spT_;};template <class T> typenameTSingle<T>::UNMaxAlign TSingle<T>::sMemory_;template <class T> typenameT* TSingle<T>::spT_ = 0;#endif // __SINGLE_H__
[解决办法]
这些看不懂啊
[解决办法]
支持一下[size=18px]Laoden[/size
[解决办法]
template <typename T>inline void SafeDelete(T*& p)//T*& p不是很懂什么意思
{ delete p; p = 0; }
//交换数据 template<typename T> void Swap(T& a, T& b) { T c(a); a = b; b = c; } //排序 template<typename T> void QuickSort(T* arr, int left, int right) { int l, r; T v; l = left; r = right; v = arr[(left + right) / 2]; while (l <= r) { while (arr[l] < v) ++l; while (arr[r] > v) --r; if (l <= r) { Swap<T>(arr[l], arr[r]); ++l; --r; } } if (l == r) l++; if (left < r) QuickSort<T>(arr, left, r); if (l < right) QuickSort<T>(arr, l, right); } int main() { int i; int a[]={1,4,2,66,22,23,5,6,8,7,99,54}; QuickSort<int>(a, 0, 11); for(i=0;i<12;i++) printf("%d\n",a[i]); double b[]={5.1,4.5,2.2,66.5,22.6,23,5,6,18.1,7,99,54}; QuickSort<double>(b, 0, 11); for(i=0;i<12;i++) printf("%f\n",b[i]); return 0; }
[解决办法]
收藏之
[解决办法]
老大想干啥呢
[解决办法]
inline static T* Create() { if (!spT_) { spT_ = new(&sMemory_) T; //这个地方进行关联的 } return spT_; }
[解决办法]
sizeof不会计算表达式。只是确定表达式的类型。
template <typename T > class is_a_ptr{public: inline static void check(){}}; template <typename T > class is_a_ptr <T*> { private: inline static void check(){}}; template <typename T>inline size_t CountOf(const T& array){ is_a_ptr<T>::check(); return sizeof(array) / sizeof(array[0]);}
[解决办法]
//判断参数类型是否是无符号类型,当然只限于有序类型template<class T>inline bool IsUnsigned(T){return ((T)-1 > 0);}
[解决办法]
还是不太明白,可以直接取地址的呀?对于成员函数,这种拷贝其实也没有什么意义,主要是数据转换。
class tt
{
public:
int i;
};
int main()
{
tt t;
int *p=&t.i;
cout<<*p<<endl;
*p=0;
cout<<*p<<endl;
return 0;
}
我汗了,template的用法如此奇特!!!模板推演,神奇啊!!!!!!!!
[解决办法]
收藏
[解决办法]
顶一下,C++的模板一直是我软肋
[解决办法]
留下足迹,方便查询!!!
[解决办法]
关注此贴!
[解决办法]
境界没到,珍藏了!
[解决办法]
template <typename InputIterator, typename Sel>
InputIterator Select(InputIterator st, InputIterator ed, Sel func)
{
if (distance(st,ed)<=1) return ed;
InputIterator i=st, j=ed;
j--;
while (distance(i,j)>0)
{
while (func(*i)&&distance(i,j)>0) i++;
while (!func(*j)&&distance(i,j)>0) j--;
if (distance(i,j)>=0)
{
swap(*i, *j);
i++;
j--;
}
}
for (InputIterator i = st; i != ed; i++) if (!func(*i)) return i;
return ed;
}
例子是快排:
func(a)相当于绑定第二个参数为a的std::less类
template <typename T, typename Func>
void qsort(T *st, T *ed, Func func)
{
if (distance(st,ed)<=10)
{
for (T *p = st; p!=ed; p++)
{
int *q = p; q++;
for (;q!=ed; q++)
if (*p > *q) swap(*p, *q);
}
return ;
}
//Select Less or Equal
T* mid = Select(st+1, ed, func(*st));
if (mid == ed) return;
swap(*st, *(mid-1));
qsort(st, mid);
qsort(mid, ed);
}
[解决办法]
不能编辑
补充说明上一楼遗漏的文字
发一个STL风格的选择函数,没有检查迭代器:
输入是 1.迭代器起点st 2.迭代器终点(不含ed) 3.选择函数func
输出是一个迭代器p, [st, p)是满足条件区间
[解决办法]
当然 你可以考虑使用copy_if或者等价的实现如
template<typename InputIterator, // 一个copy_if的
typename OutputIterator, // 正确实现
typename Predicate>
OutputIterator copy_if(InputIterator begin,
InputIterator end,
OutputIterator destBegin,
Predicate p) {
while (begin != end) {
if (p(*begin))*destBegin++ = *begin;
++begin;
}
return destBegin;
}
[解决办法]
[Quote=引用:]
引用:
CountOf那个函数模板是不是这么来实现更好点呢?
template<class T, size_t N>inline size_t CountOf(const T(&)[N]){return N;}
[解决办法]
template<typename T>inline void SafeDelete(T*& p)
{ delete p; p = 0; }
template<typename T>inline void SafeDeleteArray(T*& p)
{ delete[] p; p = 0; }
这两个换成这样的好些
template<typename T>inline void SafeDelete(T*& p)
{ enum{ ensure_comletetype = sizof(T) }; delete p; p = 0; }
template<typename T>inline void SafeDeleteArray(T*& p)
{ enum{ ensure_comletetype = sizof(T) }; delete[] p; p = 0; }
[解决办法]
//将元素累加到maptemplate<typename KEY, typename VALUE>inline void AddOneToMap(map<KEY, VALUE>& mp, const KEY& key, const VALUE& value){ map<KEY, VALUE>::iterator it = mp.find(key); if (it != mp.end()) { it->second += value; } else { mp.insert(make_pair(key, value)); }}