其中比较有新意的一点就是稻草人函数MakeT的使用,它解决了在T无法被构造的时候这个测试类无法使用的问题,但是却有一个小小的问题。那就是当T是数组的时候,函数是不允许回传数组的,所以这个类又无法使用了,可能作者未考虑到这种情况,毕竟很少有人变态到把完整的数组信息传来传去,但是我却在实际使用中遇到了。
template < typename T,typename U > class TestType ... { typedef char Small; typedef struct...{char buf[2];} Big; Small Test(T); Big Test(...); T MakeT();public: enum ...{exist = (sizeof(Small) == sizeof(Test(MakeT())))};} ; class Base ... {} ;template < class T > void doSomething(T & data) ... { TestType<T,Base[100]>::exist;} int _tmain( int argc, _TCHAR * argv[]) ... { Base buf[100]; doSomething(buf); return 0;}首先我使用了模板策略获得了函数传来的完整数组信息,然后为了确定数组是否是特定一个数组类型的时候,我想到了这个测试类,它报错了,编译器抱怨说函数回传了一个数组。
从我的认知范围里,我无法获得一个同样封装模式但可以解决这个问题的类,也许你想到这样:
template < typename T,typename U > class TestType ... { typedef char Small; typedef struct...{char buf[2];} Big; Small Test(T); Big Test(...); T MakeT(); template <typename M> GetRawType(M) ...{ return MakeT(); } template <typename M> GetRawType(M[]) ...{ return M; };public: enum ...{exist = (sizeof(Small) == sizeof(Test( GetRawType(T()) )))};} ;但这成了鸡生蛋还是蛋生鸡的问题。
我尝试了很多办,包括类型选择和试图利用转掉const的策略转掉[],但是都没有成功,buf[100]已经在模板替换的时候被作为一个独立的类型了,我的类型选择必须得做成这样才可以运作:
template < typename T > struct IsArray ... { typedef T Result; enum ...{result = 2};} ;template < typename T > struct IsArray < T[ 100 ] > ... { typedef T Result; enum ...{result = 1};} ;template < typename T > void doSomething(T & buf) ... { cout<<IsArray<T>::result<<endl;} int _tmain( int argc, _TCHAR * argv[]) ... { char buf[100]; doSomething(buf); return 0;}注意我已经固化了这个数组T[100],这样的一个模板是没有任何实用价值的。
但是,到现在为止,我已有的知识无法让我封装出一个类库性质的东西,可是却可以得到这类问题的解法,当是真的要ASSERT某个特定类型是否为特定的具有完整信息的数组的时候,你可以这样:
template < typename T > struct IsArray ... { enum ...{isarray = false};} ;template < typename T > struct IsArray < T[ 100 ] > ... { enum ...{isarray = true};} ;template < typename T > void doSomething(T & buf) ... { MyAssert(IsArray<T>::isarray);} int _tmain( int argc, _TCHAR * argv[]) ... { char buf[100]; doSomething(buf); return 0;}注意这里的MyAssert是使用模板做成的编译期的assert功能。
这样验证特定数据是否是数组的问题得到了一个解法,虽然没有现成的类可用,但是毕竟你碰到这种情况的时候不多,而且我真的无法想到更好的办法了。
