Val*_*kea 10 c++ templates variadic c++11
我正在研究一个事件库,我遇到了Variadic模板的问题.
一切都工作得非常好,除了我不能将参考作为参数传递...
这是一个非常简化的例子,用来揭露我的问题.
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;
}
Run Code Online (Sandbox Code Playgroud)
当我将所有DelayedSignal实例注册到单个std :: list实例中时,我希望避免在类本身上使用模板,这就是我在构造函数上使用模板的原因.我还可以使用纯虚拟类作为所有DelayedSignal的基础,并将指向虚拟类的指针注册到std :: list中,但我认为最好尽量减少虚拟方法的使用,我真的对这个问题感兴趣...
正如您在此示例中所看到的,如果它们被激活,test02和test04将返回错误.DelayedSignal_DebugHelper几乎与DelayedSignal相同,只是它在最后一个构造函数而不是Args模板(方法模板参数)上使用ArgsBis(类模板参数),否则它不起作用(与DelayedSignal一样).Args是被接受的,void(C::*func)(Args...)但并不是ArgsBis... args因为它们在同一个构造函数声明中.
据我所知,只要没有引用DelayedSignal test04(&Signal<void, Klass>::fire, signal_01, k);,没有引用(例如)或多个参数(或没有)就没有问题.
反正有没有解决这个问题?
谢谢.
霍华德·欣南特 (Howard Hinnant) 是对的...您拥有的另一种可能性是到处使用引用,例如:
#include <iostream>
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 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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1994 次 |
| 最近记录: |