1. 程式人生 > >C++類模板的成員函式模板寫法

C++類模板的成員函式模板寫法

這幾天本來想將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();
};

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++中編譯會出錯!