這幾天本來想將Lua_Tinker移植到Linux上去的,但是由于VC中的模板寫法與gcc中的模板寫法有些不同之處,比如下面一段代碼:
struct pop_
{
template<typename T>
static T invoke(lua_State *L, int index) { return lua2type<T>::invoke(L, index); }
template<>
static char* invoke(lua_State *L, int index) { return (char*)lua_tostring(L, index); }
template<>
static const char* invoke(lua_State *L, int index) { return (const char*)lua_tostring(L, index); }
};
在VS2003中就沒有問題,但是在Linux中用g++編譯就會出現問題,g++不支持這種寫法。因為Lua_Tinker全是模板,而且有很多這種模板與全特化同在一個類或者結構中的模板,而至今(到筆者寫稿時為止)也沒有找到一種解決方案可以將上面所示代碼正確移植到Linux,所以Lua_Tinker向Linux的移植到現在為止還并沒有成功!雖然,這次移植并沒有成功,但是我還是在這次移植中得到了許多關于模板的寫法的經驗。下面就介紹一下類模板中的函數模板在類內定義與類外定義的兩種寫法:
第一種:類內定義
// 類內定義寫法
template<typename T>
class CA
{
template<typename RET>
static RET f()
{
RET t;
return t;
}
};
第二種:類外定義
// 類外定義的寫法
template<typename T>
class CA
{
template<typename RET>
static RET f()
{
RET t;
return t;
}
};
template<typename T>
template<typename RET>
RET CA<T>::f()
{
RET t;
return t;
}
以上兩中寫法在VC中和g++中都可以順利地編譯!關于文章開頭的第一段代碼,如何寫才能在g++中順利編譯呢?由于g++不支持類模板中函數模板全特化的template<>寫法,但支持template<int>,template<char*>等等的全特化寫法,所以將文章第一段代碼寫為如下形式即可在g++中編譯通過:
struct pop_
{
template<typename T>
static T invoke(lua_State *L, int index) { return lua2type<T>::invoke(L, index); }
template<char*>
static char* invoke(lua_State *L, int index) { return (char*)lua_tostring(L, index); }
template<const char*>
static const char* invoke(lua_State *L, int index) { return (const char*)lua_tostring(L, index); }
};
但是,由于g++不支持將void,float,double三種類型作為模板參數,所以template<void>,template<float>,template<double>在g++中編譯會出錯!