2013-05-08 10 views
8

मेरे आवेदन में मेरे पास बहुत सारे लॉग हैं। मैं errorsLogger नामक एक स्थान पर सभी लॉग से सभी त्रुटियों को जमा करता हूं। मैं इसे इस तरह से क्रियान्वित किया है:किसी अन्य फ़ंक्शन में तर्कों की परिवर्तनीय संख्या को कैसे आगे बढ़ाया जाए?

static Logger errorsLogger; 

.... 

void Logger::Error(std::string format, ...) { 
    va_list arglist; 
    va_start(arglist, format); 

    if (this != &errorsLogger) { 
     errorsLogger.Error(format, arglist);  // how to forward parameters? 
    } 

    vfprintf(logFile, , format.c_str(), arglist); 
    fprintf(logFile, "\n"); 

    fflush(logFile); 
    va_end(arglist); 
} 

हालांकि इस कोड के रूप में की उम्मीद errorsLogger थोड़ा अजीब तार शामिल काम नहीं करता है - यह चर तर्क पारित नहीं किया था लगता है। वैध होने के लिए मेरे कोड को कैसे ठीक करें?

+1

आपको 'त्रुटि' का एक संस्करण चाहिए जो एक ['va_list'] (http://en.cppreference.com/w/cpp/utility/variadic/va_list) लेता है। – BoBTFish

+1

अपने लॉगर के इंटरफेस को बदलने पर विचार करें, इसलिए यह 'ओस्ट्रीम' जैसा दिख रहा है, आप इस तरह की चीजें करने में सक्षम होंगे: 'लॉगर :: त्रुटि() << "वेरिएबल एक्स है" << x;' वास्तव में 'लॉगर :: त्रुटि() 'एक ओस्ट्रीम और ' – piokuc

+0

वापस कर सकता है क्या मैं केवल पहले चरण के रूप में स्ट्रिंग को प्रारूपित कर सकता हूं और फिर std :: string को आगे बढ़ा सकता हूं? – javapowered

उत्तर

13

सी में इस के विशिष्ट निर्माण दो काम करता है, एक है कि ... स्वीकार करता है और एक है कि स्वीकार करता है एक va_list (जैसे, printfvprintf बनाम)। सी ++ में यह भार के साथ ऐसा करना सुविधाजनक है:

// public 
void Logger::Error(const std::string& format, ...) { 
    va_list args; 
    va_start(args, format); 
    Error(format, args); 
    va_end(args); 
} 

// private 
void Logger::Error(const std::string& format, va_list args) { 
    if (this != &errorsLogger) 
     errorsLogger.Error(format, args); 

    vfprintf(logFile, format.c_str(), args); 
    fprintf(logFile, "\n"); 
    fflush(logFile); 
} 

सी ++ 11 का उपयोग करना, यह एक variadic टेम्पलेट के साथ सीधे करने के लिए संभव है। आप सी-स्टाइल वैरिएडिक फ़ंक्शंस में तर्क भी अग्रेषित कर सकते हैं।

template<class... Args> 
void Logger::Error(const std::string& format, Args&&... args) {  
    if (this != &errorsLogger) 
     errorsLogger.Error(format, std::forward<Args>(args)...); 

    fprintf(logFile, format.c_str(), std::forward<Args>(args)...); 
    fprintf(logFile, "\n"); 
    fflush(logFile); 
} 
+0

सी निश्चित रूप से सी variadic कार्यों को आगे बढ़ाने के लिए आप चरणीय टेम्पलेट का उपयोग कर सकते हैं। [लाइव उदाहरण] (http://melpon.org/wandbox/permlink/0fbi8R2PCrOJkeFv) –

4

संक्षेप में, आप नहीं कर सकते।

आप जो भी कर सकते हैं वह समकक्ष सदस्य फ़ंक्शन लिखता है जो परिवर्तनीय तर्कों के बजाय va_list लेता है, और आरंभ में va_list को पास करता है।

+0

आप इसे क्यों कम कर रहे हैं? –

+1

शायद कोई इसे कम करना चाहता था? या वे एक कार्बनिक रसायनज्ञ हैं जो ओसी (ओएच) ₂ लिखना पसंद करते हैं? वास्तव में कहना मुश्किल है। –

+0

@ कोडीग्रे एलओएल, कार्बनिक रसायनविदों के बारे में अच्छी बात है। –

0

कि काम करने के लिए, Logger::Error बल्कि ... fprintf की तरह के रूप में परिवर्तित युक्तियों की तुलना में बहुत vfprintf की तरह, एक va_list एक पैरामीटर के रूप को स्वीकार करने की घोषणा की है, होगा।

संबंधित मुद्दे

 संबंधित मुद्दे