我試圖將一個通用方法調用器(用於C++ OO/v8橋),使用可變參數模板元編程來構建參數列表,轉換爲本機類型,最後執行附加的方法,一旦進入PARAM列表是空的(並因此傳出內置):Variadic模板候選不匹配
template<typename... PARAMS>
class InvocationBuilder {
public:
void invoke(const Arguments &source, PARAMS&... params) {
cout << "Invoke" << endl;
(instance->*(method))(*params...);
}
template<class HEAD, class ... TAIL>
void invoke(const Arguments &source, PARAMS... params) {
cout << "Expand" << endl;
Type<HEAD> param(source[sizeof...(PARAMS)]);
InvocationBuilder<PARAMS..., HEAD> builder;
builder.template invoke<TAIL...>(source, params..., *param);
}
Type類僅僅是一個包裝來創建V8參數的堆棧作用域變體(以便,例如,可以使用字符*串而在調用期間的範圍內,但是一旦調用返回就自動清除)。
現在,當實際的橋樑調用此,有一個參數列表,使用:
InvocationBuilder<> builder;
builder.template invoke<ARGS...>(args);
哪裏ARGS是V8 ::參數參考。
編譯器正確鏈接參數生成的每一步,但無法匹配非模板化的invoke()方法,以實際執行本機C++方法。
錯誤消息是如下:
include/link/function.hh: In member function 'void sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::InvocationBuilder<PARAMS>::invoke(const v8::Arguments&, PARAMS ...) [with HEAD = int, TAIL = {}, PARAMS = {int, int}, CLASS = SomeClass, ARGS = {int, int, int}]':
include/link/function.hh:65:6: recursively instantiated from 'void sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::InvocationBuilder<PARAMS>::invoke(const v8::Arguments&, PARAMS ...) [with HEAD = int, TAIL = {int}, PARAMS = {int}, CLASS = SomeClass, ARGS = {int, int, int}]'
include/link/function.hh:65:6: instantiated from 'void sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::InvocationBuilder<PARAMS>::invoke(const v8::Arguments&, PARAMS ...) [with HEAD = int, TAIL = {int, int}, PARAMS = {}, CLASS = SomeClass, ARGS = {int, int, int}]'
include/link/function.hh:47:5: instantiated from 'v8::Handle<v8::Value> sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::run(const v8::Arguments&) [with CLASS = SomeClass, ARGS = {int, int, int}]'
test.cc:41:1: instantiated from here
include/link/function.hh:65:6: error: no matching function for call to 'sjs::link::InstanceFunctionVariadic<SomeClass, int, int, int>::InvocationBuilder<int, int, int>::invoke(const v8::Arguments&, int&, int&, int)'
include/link/function.hh:65:6: note: candidate is:
include/link/function.hh:61:10: note: template<class HEAD, class ... TAIL> void sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::InvocationBuilder::invoke(const v8::Arguments&, PARAMS ...) [with HEAD = HEAD, TAIL = {TAIL ...}, PARAMS = {int, int, int}, CLASS = SomeClass, ARGS = {int, int, int}]
消息清楚地表明,前三個步驟,一個C++實例方法空隙測試(INT A,INT B,INT c)所示,工作正常,使用Type提取參數並傳遞結果 - 但我無法弄清楚爲什麼最終的invoke()沒有被正確地使用。我試圖完全專門化它,但後來我得到關於命名空間範圍(我假設是因爲該方法是模板類的成員)以外的專門化的錯誤消息。
我也嘗試轉移傳入/傳出參數列表,以便傳入是在類variadic模板中,而傳出的方法專門調用類的調用 - 但我碰到了「對不起,未實現「關於將可變參數解包到靜態模板中的消息。我也試過通過使用通用的單個可變參數模板,然後專門爲HEAD/TAIL案例,專門爲空集案例,但後來我得到立即含糊(可能因爲頭/尾值實際上並不作爲參數傳遞 - 僅在模板中)。
但到目前爲止,沒有骰子。任何人有任何其他想法,或可以解釋我要去哪裏錯了?
不要混合模板和非模板重載。過載的解決方法非常棘手,可能無法實現您的想法。你可以叫一個人'invoke_impl'左右。 – 2012-02-12 14:12:15
這個問題是我想要的方法是一個自動終止參數列表遞歸,而不是一個特定的額外情況。 我實際上嘗試了一個單獨的案例,使用sizeof ...(PARAMS)來確定列表是否構建,但這意味着調用方法會針對每個子階段構建,並且參數計數錯誤,因此會給出編譯錯誤。 – jka6510 2012-02-12 14:13:56
對不起,我實際上沒有看到這個,所以我不應該說什麼。我看不出爲什麼你需要非靜態函數;通常這樣的助手類只使用靜態成員函數完成,因爲助手本身沒有並且不需要狀態。也許你是在混合責任太多,但我不可能告訴。我相信其他人將能夠提供一些實際有用的反饋。 – 2012-02-12 14:16:03