可変数の引数を持つオーバーロードのコードの重複 (または醜いマクロ) を避けるために、古いテンプレートの一部を可変長バージョンに置き換え始めました。
私が遭遇し、まだ解決されていない問題の 1 つは、次のとおりです。
これが私の例です:
#include <tuple>
// old version to be replaced
namespace old_version
{
template<typename T> struct struct_const_deref { typedef T Type; };
template<typename T> struct struct_const_deref < const T& > { typedef T Type; };
template < typename F, typename T1 >
void exec(F* pObj, void(F::*pFct)(T1))
{
typename struct_const_deref<T1>::Type t1;
// some code that fills t1
(pObj->*pFct)(t1);
}
template < typename F, typename T1 , typename T2 >
void exec(F* pObj, void(F::*pFct)(T1, T2))
{
typename struct_const_deref<T1>::Type t1;
typename struct_const_deref<T2>::Type t2;
// some code that fills t1, t2
(pObj->*pFct)(t1, t2);
}
}
// new variadic version
namespace variadic
{
template< typename... Args > struct struct_const_deref_tuple { typedef std::tuple< Args... > Tuple; };
template< typename... Args > struct struct_const_deref_tuple < const Args&... > { typedef std::tuple< Args... > Tuple; };
template < typename F, typename... Args >
void exec(F* pObj, void(F::*pFct)(Args... args))
{
typename struct_const_deref_tuple< Args... >::Tuple tN;
// some code that fills tN
// some helper template that 'extracts' the tuple and calls (pObj->*pFct)(ExtractedArgs...)
}
}
struct Test
{
void foo(int i) {}
void bar(const float& f, const int& i) {}
void buu(const float& f, int i) {}
};
int main(int argc, char* argv[])
{
Test t;
old_version::exec(&t, &Test::foo); // ok
old_version::exec(&t, &Test::bar); // ok
old_version::exec(&t, &Test::buu); // ok
variadic::exec(&t, &Test::foo); // ok
variadic::exec(&t, &Test::bar); // ok
variadic::exec(&t, &Test::buu); // fails (the struct_const_deref_tuple does not 'catch' my case; 'tN' will be std::tuple<const float&, int>
return 0;
}
古いソリューションでは引数の数ごとにバージョンが必要だったので、可変引数のソリューションに置き換えたいと思います。
残念ながら、可変長バージョンは失敗します
Test::buu
なぜなら tN は
std::tuple<const float&, int>
しかし、それは明らかにする必要があります
std::tuple<float, int>
私が働くために。
どんなアイデアも歓迎します:)