次のコードがあります。
lib.hxx:
template <typename C, typename R, typename ... Args>
R Lib::extract_call(lua_State* L, R(C::*method)(Args...))
{
return static_cast<C*>(this)->*method(extract_data<Args>(L)...);
}
lib.cc:
template <>
std::string Lib::extract_data(lua_State* L)
{
if (! lua_isstring(L, -1))
{
return "";
}
return lua_tostring(L, -1);
}
[...] // Other specializations following
プロジェクトに lua を埋め込んでいます。現在、lua からメソッドを呼び出し、ディスパッチャーから lua スタックから引数を自動的に抽出する方法を探しています。これらの「単純な」テンプレートから、パラメーターで指定された lua スタックからデータを抽出するために必要な呼び出しを、入力エラーなしで簡単に生成できます。
しかし、私の問題は、extract_data<Args>(L)...
がアンパックされたとき、すべてのextract_data
呼び出しの評価の順序が指定されていないことです (最適化の目的で、標準で述べられているように)。lua スタックからデータを抽出する順序は本当に重要です。一方、これらの呼び出しのすべてをイニシャライザ リストに再グループ化することはできません。それらは異なる型だからです。
したがって、呼び出しが特定の順序になるようにするにはどうすればよいですかextract_data
、または少なくともメンバーポインター関数に引数を渡す自動化された方法を維持するにはどうすればよいですか?
EDIT :呼び出しを元に戻す必要があることを忘れていましたが、これは言語メカニズムでは達成できないと思います。したがって、これが私の解決策です。通常の非可変個のテンプレートに戻ります。
template <typename C, typename R, typename A1>
R Lib::extract_call(lua_State* L, R(C::*method)(A1))
{
return (static_cast<C*>(this)->*method)(extract_data<A1>(L));
}
template <typename C, typename R, typename A1, typename A2>
R Lib::extract_call(lua_State* L, R(C::*method)(A1, A2))
{
A2 b = extract_data<A2>(L);
A1 a = extract_data<A1>(L);
return (static_cast<C*>(this))->*method(a,b);
}
template <typename C, typename R,
typename A1, typename A2, typename A3>
R Lib::extract_call(lua_State* L, R(C::*method)(A1, A2, A3))
{
A3 c = extract_data<A3>(L);
A2 b = extract_data<A2>(L);
A1 a = extract_data<A1>(L);
return (static_cast<C*>(this))->*method(a,b,c);
}
// And so on up to 8 arguments