2013-03-05 66 views
2

所以,我最近使用C++ 11的可變參數模板構建了一個委託系統,它的功能就像魅力一樣。多變量模板代表系統

但是在系統中,我已經在創建時給函數創建了參數(正如我所願),但是現在我還想在調用時傳遞一些(可變數量)參數-時間。爲了達到這個目的,我去了並重新編寫了我的代碼,然而我卻在那裏得到了這些問題。

error: parameter packs must be at the end of the parameter list 
sorry, unimplemented: cannot expand ‘Arguments ...’ into a fixed-length argument list 
error: type/value mismatch at argument 1 in template parameter list for ‘template<<declaration error>, class ... Params> class FunctionDelegate’ 

...還有更多的問題來了,所以這裏有一個小問題引發了這個問題;

template<typename... Params> 
class Runnable 
{ 
    public: 
     virtual void invoke(tuple<Params...> params) = 0; 
     virtual ~Runnable() 
     { 
     } 
}; 

這是我的兩個代表(FunctionDelegate和ObjectDelegate)的父類。這曾經是一個無模板的類(因爲invoke沒有任何參數),但是因爲我有一個variadic模板列表,所以我不得不修改我的子類(顯然),並且我剛添加了另一個可變參數模板給他們;

template<typename... Arguments, typename... Params> 
class FunctionDelegate : public Runnable<Params...> 
{ 
    public: 
     typedef void (*FunctionType)(Arguments..., Params...); 

     FunctionDelegate(FunctionType function, tuple<Arguments...> args) 
      : function(function), args(args) 
     { 
     } 

     void invoke(tuple<Params...> params) 
     { 
      callFunction(typename gens<sizeof...(Arguments)>::type(), params, typename gens<sizeof...(Params)>::type()); 
     } 
    private: 
     template<int... S, int... R> 
     void callFunction(seq<S...>, tuple<Params...> params, seq<R...>) 
     { 
      function(get<S>(args)..., get<R>(params)...); 
     } 
    private: 
     FunctionType function; 
     tuple<Arguments...> args; 
}; 

但是,這似乎不被允許,至少這是我懷疑,所以;

  1. 它是否允許有兩個可變模板列表?
  2. 有沒有辦法,我可以提示編譯器,關於哪個列表到哪個列表? (即在構造函數中使用的參數轉到參數,其餘的參數爲參數)。
  3. 如果沒有辦法做到這一點(使用兩個可變模板列表),是不是可以使用一個,參數和參數在相同的可變參數列表中,然後簡單地將參數分解到構造函數中?
  4. 有沒有其他方法可以實現我正在嘗試的? (除了使用普通的舊的,非類型檢查的可變參數傳遞之外)。

歡迎任何幫助或見解。

+0

「是否允許有兩個可變模板列表?」 - 不在類模板上。 – Xeo 2013-03-05 11:34:54

+0

@Xeo:那麼它在哪裏允許,你知道它在標準中的位置嗎? – Skeen 2013-03-05 11:35:33

+0

安迪在這方面比我快一點。 :) – Xeo 2013-03-05 11:35:57

回答

4

關於你的前兩個問題(答案是 「沒有」 和 「」),第14.1段的C++標準11/11規定:

如果模板參數類模板或別名模板的默認模板參數的每個後續 模板參數應具有提供的默認模板參數或模板參數 包。 如果主類模板或別名模板的模板參數是模板參數包,它應該是最後一個模板參數。函數模板的模板參數包不得爲 ,後跟另一個模板參數,除非可以推導出該模板參數或者具有默認的參數(14.8.2) 。 [實施例:

template<class T1 = int, class T2> class B; // error 
// U cannot be deduced or specified 
template<class... T, class... U> void f() { } 
template<class... T, class U> void g() { } 

末端示例]

你的實施例清楚地違反以粗體顯示的句子,禁止具有在(主)類模板多於一個模板參數包。

+0

3)不,不是真的,拆分可變包是非平凡的; 4)你可以將這些參數打包成兩個'元組',並使用部分特化來提取包。 – Xeo 2013-03-05 11:37:21

+0

@Xeo:你可以舉一個例子來說明如何使用部分專業化來解開你在(4)中提到的兩個元組? – Skeen 2013-03-05 11:39:01

+0

@Skeen:ForEveR提供了一個例子 – 2013-03-05 11:39:20

5

不,你不能使用這樣的代碼。您可以使用下面例如

template<typename... Params> 
class FunctionDelegate; 

template<typename Arguments, typename Params> 
class FunctionDelegate; 

爲XEO建議。

template<typename... Arguments, typename... Params> 
class FunctionDelegate<tuple<Arguments...>, tuple<Params...>> : 
public Runnable<Params...> { // }; 
+0

雖然我會讓主模板採用'typename Arguments,typename Params'。 – Xeo 2013-03-05 11:40:41

+0

我得到了類的工作,使用代碼建議,但我似乎讓我的makeDelegate函數的工作,我已經在另一個問題上發佈這個問題; http://stackoverflow.com/questions/15223132/makedelegate-function-not-working – Skeen 2013-03-05 11:54:04