पर संदर्भ पास करना मैं एक इवेंट लाइब्रेरी पर काम कर रहा हूं और मुझे वैराडिक टेम्पलेट्स के साथ समस्या का सामना करना पड़ रहा है।वैराडिक टेम्पलेट्स
सभी तथ्य को छोड़कर बहुत अच्छा है कि मैं पैरामीटर के रूप में संदर्भ पारित नहीं हो सकता काम कर रहा है ...
यहाँ एक बहुत ही सरल उदाहरण मेरी समस्या का पर्दाफाश करने में लिखा है।
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;
}
मैं एक एकल std :: सूची उदाहरण में सभी DelayedSignal उदाहरणों रजिस्टर के रूप में मैं वर्ग पर ही टेम्पलेट का उपयोग कर से बचने के लिए चाहते हैं, और यही कारण है कि मैं बजाय कंस्ट्रक्टर्स पर टेम्पलेट का उपयोग है। मैं सभी विलम्बित सिग्नल के लिए शुद्ध वर्चुअल क्लास का उपयोग कर सकता हूं और वर्चुअल क्लास को std :: सूची में पॉइंटर्स पंजीकृत कर सकता हूं लेकिन मुझे लगता है कि आभासी तरीकों के उपयोग को कम करना सबसे अच्छा है और मैं वास्तव में इस समस्या से चिंतित हूं ...
जैसा कि आप इस उदाहरण में देख सकते हैं, test02 और test04 वापसी त्रुटियों को सक्रिय करते हैं। DelayedSignal_DebugHelper देरी सिग्नल के लगभग समान है, इस तथ्य को छोड़कर कि यह ArgsBis (विधि टेम्पलेट तर्क) के बजाय अंतिम कन्स्ट्रक्टर पर ArgsBis (एक क्लास टेम्पलेट तर्क) का उपयोग करता है, अन्यथा यह काम नहीं करता है (देरी से सिग्नल के साथ)। void(C::*func)(Args...)
पर Args स्वीकार किए जाते हैं लेकिन ArgsBis... args
के साथ नहीं है, इस तथ्य के बावजूद कि वे एक ही निर्माता घोषणा में हैं।
जहां तक मुझे पता है, संदर्भों के बिना कोई समस्या नहीं है (उदाहरण के लिए DelayedSignal test04(&Signal<void, Klass>::fire, signal_01, k);
) या एकाधिक पैरामीटर (या कोई नहीं) जब तक कोई संदर्भ नहीं है।
क्या इस समस्या को ठीक करने के लिए वैसे भी है?
धन्यवाद।
संकलक संस्करण है? –
@ वॉल्के क्या आपको इसे C++ 0x से टैग नहीं करना चाहिए? मैंने आपके समाधान को संकलित करने की कोशिश की और यह सोच रहा था कि यह विजुअल स्टूडियो 2011 में क्यों काम नहीं कर रहा था; विविध टेम्पलेट्स देखने के बाद, मुझे अभी एहसास हुआ कि यदि खोज सही है, तो यह एक नई सुविधा है।वैसे भी कंपाइलर्स वास्तव में इसका समर्थन करते हैं? – leetNightshade
@ स्लेट: जोड़ा गया टैग। यह सुविधा संस्करण 4.3 के बाद g ++ द्वारा समर्थित है - अधिक जानकारी के लिए यह लिंक देखें: http://gcc.gnu.org/projects/cxx0x.html – TonyK