イベントライブラリに取り組んでいますが、可変個引数テンプレートで問題が発生しています。
参照をパラメーターとして渡すことができないという事実を除いて、すべてが非常にうまく機能しています...
これは私の問題を明らかにするために書かれた非常に単純化された例です。
struct DelayedSignal
{
~DelayedSignal ()
{ std::cout << "~DelayedSignal CLOSE" << std::endl; }
template<class C, class... Args>
DelayedSignal ( void(C::*func)(Args...), C& obj )
{ std::cout << "DelayedSignal INIT - 03 - pointer to method & pointer to class instance (Arg num: " << sizeof...(Args) << ")" << std::endl; }
template<class C, class... Args>
DelayedSignal ( void(C::*func)(Args...), C& obj, Args... args )
{
std::cout << "DelayedSignal INIT - 04 - pointer to method & pointer to class instance & arguments (Arg num: " << sizeof...(Args) << ")" << std::endl;
}
};
template<class... ArgsBis>
struct DelayedSignal_DebugHelper
{
~DelayedSignal_DebugHelper ()
{ std::cout << "~DelayedSignal_DebugHelper CLOSE" << std::endl; }
template<class C, class... Args>
DelayedSignal_DebugHelper ( void(C::*func)(Args...), C& obj )
{ std::cout << "DelayedSignal_DebugHelper INIT - 03 - pointer to method & pointer to class instance (Arg num: " << sizeof...(Args) << ")" << std::endl; }
template<class C, class... Args>
DelayedSignal_DebugHelper ( void(C::*func)(Args...), C& obj, ArgsBis... args ) // Need to use ArgsBis instead of Args to make it work
{
std::cout << "DelayedSignal_DebugHelper INIT - 04 - pointer to method & pointer to class instance & arguments (Arg num: " << sizeof...(Args) << ")" << std::endl;
}
};
template < class Tr, class... Args >
struct Signal
{
void fire ( Args... args ) { std::cout << "Signal::fire::" << sizeof...(Args) << std::endl; }
};
struct Klass {};
int main()
{
std::string str1("Blop"); // Will be used as reference
Klass k; // Will be used as reference
Signal<void, Klass&> signal_01;
Signal<void, std::string&> signal_02;
std::cout << "====== DelayedSignal :: needed for production purpose ===============" << std::endl;
// OK
DelayedSignal test01(&Signal<void, std::string&>::fire, signal_02);
// HERE IS THE PROBLEM
//DelayedSignal test02(&Signal<void, std::string&>::fire, signal_02, str1);
// OK
DelayedSignal test03(&Signal<void, Klass&>::fire, signal_01);
// HERE IS THE PROBLEM
//DelayedSignal test04(&Signal<void, Klass&>::fire, signal_01, k);
std::cout << "====== DelayedSignal_DebugHelper :: used only for debug purpose ======" << std::endl;
// OK
DelayedSignal_DebugHelper<std::string&> test05(&Signal<void, std::string&>::fire, signal_02);
// OK
DelayedSignal_DebugHelper<std::string&> test06(&Signal<void, std::string&>::fire, signal_02, str1);
// OK
DelayedSignal_DebugHelper<Klass&> test07(&Signal<void, Klass&>::fire, signal_01);
// OK
DelayedSignal_DebugHelper<Klass&> test08(&Signal<void, Klass&>::fire, signal_01, k);
return 1;
}
すべてのDelayedSignalインスタンスを単一のstd::listインスタンスに登録するときに、クラス自体でテンプレートを使用することを避けたいので、代わりにコンストラクターでテンプレートを使用します。すべてのDelayedSignalのベースとして純粋仮想クラスを使用し、仮想クラスへのポインターをstd :: listに登録することもできますが、仮想メソッドの使用を最小限に抑えるのが最善だと思います。この問題に本当に興味があります...
この例でわかるように、test02とtest04は、アクティブ化されるとエラーを返します。DelayedSignal_DebugHelperは、Argsテンプレート(メソッドテンプレート引数)の代わりに最後のコンストラクターでArgsBis(クラステンプレート引数)を使用するという事実を除いて、DelayedSignalとほぼ同じです。それ以外の場合は、(DelayedSignalのように)機能しません。Argsは受け入れられますが、同じコンストラクター宣言に含まれているという事実にもかかわらず、受け入れられvoid(C::*func)(Args...)
ません。ArgsBis... args
私の知る限り、参照がない限り(DelayedSignal test04(&Signal<void, Klass>::fire, signal_01, k);
たとえば)、または複数のパラメーターがない(またはない)限り、問題はありません。
この問題を解決する方法はありますか?
ありがとうございました。