C ++ में विभिन्न प्रकार के तर्क?


293

मैं एक फ़ंक्शन कैसे लिख सकता हूं जो एक चर संख्या के तर्कों को स्वीकार करता है? क्या यह संभव है, कैसे?


49
इस समय C ++ 11 के साथ इस प्रश्न के उत्तर बहुत भिन्न होंगे
K-ballo

1
@ कश्मीर ballo मैं सी ++ 11 उदाहरण के रूप में अच्छी तरह से जोड़ा के बाद से हाल ही में एक सवाल यह एक ही बात हाल ही में पूछा और मैं इसे बंद करने का औचित्य साबित करने में यह आवश्यक एक महसूस किया stackoverflow.com/questions/16337459/...
Shafik Yaghmour

1
मेरे जवाब के साथ- साथ पूर्व C ++ 11 विकल्प भी जोड़े , इसलिए अब इसे उपलब्ध विकल्पों में से अधिकांश को कवर करना चाहिए।
शफीक यघमौर

@ K-ballo वहाँ afaik कोई रास्ता नहीं है इसे C ++ में करने के मामले में आपको मजबूर तर्क प्रकार की आवश्यकता है .. कोई निर्माण जैसे फू (int ... मान): / यदि आप प्रकारों की परवाह नहीं करते हैं, तो हाँ, varadic टेम्पलेट्स C ++ 11 में महान काम करता है
ग्रेवुल्फ

जवाबों:


152

आपको शायद नहीं करना चाहिए, और आप शायद वही कर सकते हैं जो आप सुरक्षित और सरल तरीके से करना चाहते हैं। तकनीकी रूप से C में तर्कों की चर संख्या का उपयोग करने के लिए आप stdarg.h को शामिल करते हैं। उस से आपको va_listटाइप के साथ-साथ तीन फ़ंक्शन मिलेंगे जो उस पर काम करते हैं va_start(), va_arg()और va_end()

#include<stdarg.h>

int maxof(int n_args, ...)
{
    va_list ap;
    va_start(ap, n_args);
    int max = va_arg(ap, int);
    for(int i = 2; i <= n_args; i++) {
        int a = va_arg(ap, int);
        if(a > max) max = a;
    }
    va_end(ap);
    return max;
}

अगर तुम मुझसे पूछते हो, यह गड़बड़ है। यह बुरा लग रहा है, यह असुरक्षित है, और यह तकनीकी विवरणों से भरा है, जिनका वैचारिक रूप से हासिल करने के लिए कुछ भी नहीं है। इसके बजाय, ओवरलोडिंग या इनहेरिटेंस / बहुरूपता, बिल्डर पैटर्न (जैसे operator<<()धाराओं में) या डिफ़ॉल्ट तर्क आदि का उपयोग करने पर विचार करें । ये सभी सुरक्षित हैं: संकलक को इस बारे में अधिक पता चल जाता है कि आप क्या करने की कोशिश कर रहे हैं, ताकि अधिक से अधिक मौके मिल सकें। इससे पहले कि आप अपना पैर उड़ा दें।


7
संभवतः, आप एक varargs फ़ंक्शन के संदर्भों को पास नहीं कर सकते क्योंकि संकलक को पता नहीं होगा कि कब मूल्य से और कब संदर्भ से गुजरना है, और क्योंकि अंतर्निहित सी मैक्रोज़ को यह नहीं पता होगा कि संदर्भ के साथ क्या करना है - पहले से ही प्रतिबंध क्या हैं आप प्रचार नियमों जैसी चीजों के कारण परिवर्तनशील तर्कों के साथ C फ़ंक्शन में जा सकते हैं।
जोनाथन लेफ़लर

3
...वाक्यविन्यास से पहले कम से कम एक तर्क प्रदान करना आवश्यक है ?
लेज़र

3
@ Lazer यह एक भाषा या पुस्तकालय की आवश्यकता नहीं है, लेकिन मानक पुस्तकालय आपको सूची की लंबाई बताने का साधन नहीं देता है। आपको यह जानकारी देने के लिए फोन करने वाले की जरूरत है या फिर किसी तरह से खुद ही इसका पता लगा लें। के मामले में printf(), उदाहरण के लिए, समारोह कितने अतिरिक्त तर्क यह चर तर्क सूची में उम्मीद करनी चाहिए यह पता लगाने की विशेष टोकन स्ट्रिंग तर्क पार्स करता है।
विल्हेमटेल

11
आपको संभवतः <cstdarg><stdarg.h>
Newacct

11
विभिन्न प्रकार के तर्क डिबग के लिए या फ़ंक्शंस / विधियों के लिए बहुत अच्छे हैं जो कुछ सरणी भरते हैं। इसके अलावा यह कई गणितीय कार्यों के लिए बहुत अच्छा है, जैसे कि अधिकतम, न्यूनतम, योग, औसत ... यह गड़बड़ नहीं है जब आप इसके साथ गड़बड़ नहीं करते हैं।
टॉम ज़ातो -

395

में सी ++ 11 आप के रूप में दो नये विकल्प है, variadic कार्यों में संदर्भ पेज वैकल्पिक खंड कहता है:

  • वेरिएडिक टेम्प्लेट का उपयोग उन कार्यों को बनाने के लिए भी किया जा सकता है जो चर संख्या में तर्क लेते हैं। वे अक्सर बेहतर विकल्प होते हैं क्योंकि वे तर्कों के प्रकारों पर प्रतिबंध नहीं लगाते हैं, अभिन्न और फ्लोटिंग-पॉइंट प्रमोशन नहीं करते हैं, और सुरक्षित हैं। (C ++ 11 के बाद से)
  • यदि सभी चर तर्क एक सामान्य प्रकार साझा करते हैं, तो एक चर :: initializer_list चर तर्कों तक पहुँचने के लिए एक सुविधाजनक तंत्र (एक अलग वाक्यविन्यास के साथ) प्रदान करता है।

नीचे एक उदाहरण है जो दोनों विकल्प दिखा रहा है ( इसे लाइव देखें ):

#include <iostream>
#include <string>
#include <initializer_list>

template <typename T>
void func(T t) 
{
    std::cout << t << std::endl ;
}

template<typename T, typename... Args>
void func(T t, Args... args) // recursive variadic function
{
    std::cout << t <<std::endl ;

    func(args...) ;
}

template <class T>
void func2( std::initializer_list<T> list )
{
    for( auto elem : list )
    {
        std::cout << elem << std::endl ;
    }
}

int main()
{
    std::string
        str1( "Hello" ),
        str2( "world" );

    func(1,2.5,'a',str1);

    func2( {10, 20, 30, 40 }) ;
    func2( {str1, str2 } ) ;
} 

यदि आप उपयोग कर रहे हैं gccया clangहम फ़ंक्शन के प्रकार हस्ताक्षर को प्रदर्शित करने के लिए PRETTY_FUNCTION जादू चर का उपयोग कर सकते हैं जो समझने में मददगार हो सकता है कि क्या हो रहा है। उदाहरण के लिए:

std::cout << __PRETTY_FUNCTION__ << ": " << t <<std::endl ;

उदाहरण में चर कार्यों के लिए निम्नलिखित परिणाम प्राप्त होंगे ( इसे लाइव देखें ):

void func(T, Args...) [T = int, Args = <double, char, std::basic_string<char>>]: 1
void func(T, Args...) [T = double, Args = <char, std::basic_string<char>>]: 2.5
void func(T, Args...) [T = char, Args = <std::basic_string<char>>]: a
void func(T) [T = std::basic_string<char>]: Hello

Visual Studio में आप FUNCSIG का उपयोग कर सकते हैं ।

अद्यतन पूर्व C ++ 11

प्री सी ++ 11 एसटीडी के लिए विकल्प :: initializer_list एसटीडी होगा :: वेक्टर या अन्य मानक कंटेनरों में से एक :

#include <iostream>
#include <string>
#include <vector>

template <class T>
void func1( std::vector<T> vec )
{
    for( typename std::vector<T>::iterator iter = vec.begin();  iter != vec.end(); ++iter )
    {
        std::cout << *iter << std::endl ;
    }
}

int main()
{
    int arr1[] = {10, 20, 30, 40} ;
    std::string arr2[] = { "hello", "world" } ; 
    std::vector<int> v1( arr1, arr1+4 ) ;
    std::vector<std::string> v2( arr2, arr2+2 ) ;

    func1( v1 ) ;
    func1( v2 ) ;
}

और के लिए वैकल्पिक variadic टेम्पलेट्स होगा variadic कार्यों हालांकि वे नहीं कर रहे हैं टाइप-सुरक्षित और सामान्य रूप में त्रुटियों की संभावना और उपयोग करने के लिए असुरक्षित हो सकता है , लेकिन केवल अन्य संभावित विकल्प का उपयोग किया जाएगा डिफ़ॉल्ट तर्क है, हालांकि यह है कि सीमित उपयोग है। नीचे दिए गए उदाहरण से जुड़े संदर्भ में नमूना कोड का एक संशोधित संस्करण है:

#include <iostream>
#include <string>
#include <cstdarg>

void simple_printf(const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);

    while (*fmt != '\0') {
        if (*fmt == 'd') {
            int i = va_arg(args, int);
            std::cout << i << '\n';
        } else if (*fmt == 's') {
            char * s = va_arg(args, char*);
            std::cout << s << '\n';
        }
        ++fmt;
    }

    va_end(args);
}


int main()
{
    std::string
        str1( "Hello" ),
        str2( "world" );

    simple_printf("dddd", 10, 20, 30, 40 );
    simple_printf("ss", str1.c_str(), str2.c_str() ); 

    return 0 ;
} 

वैरेडिक फ़ंक्शंस का उपयोग करने से उन तर्कों पर भी प्रतिबंध लग जाता है, जिन्हें आप पास कर सकते हैं, जो ड्राफ्ट C ++ मानक में विस्तृत है। 5.2.2 फंक्शन कॉल पैराग्राफ 7 :

जब किसी दिए गए तर्क के लिए कोई पैरामीटर नहीं होता है, तो तर्क को इस तरह से पारित किया जाता है कि प्राप्त फ़ंक्शन va_arg (18.7) को लागू करके तर्क का मूल्य प्राप्त कर सकता है। लॉवल्यू-टू-रिवल्यू (4.1), एरे-टू-पॉइंटर (4.2), और फ़ंक्शन-टू-पॉइंटर (4.3) मानक रूपांतरण तर्क अभिव्यक्ति पर किए जाते हैं। इन रूपांतरणों के बाद, यदि तर्क में अंकगणित, गणना, सूचक, सदस्य के लिए सूचक या कक्षा प्रकार नहीं है, तो कार्यक्रम बीमार है। यदि तर्क में गैर-POD वर्ग प्रकार (खंड 9) है, तो व्यवहार अपरिभाषित है। [...]


क्या आपके typenameबनाम classउपयोग जानबूझकर ऊपर है? यदि हां, तो कृपया समझाएं।
केविनपेयर

1
@kevinarpe जानबूझकर नहीं, हालांकि यह कुछ भी नहीं बदलता है।
शफीक यघमौर

संभवतः आपका पहला लिंक इसके बजाय en.cppreference.com/w/cpp/language/variadic_arguments पर होना चाहिए।
एलेक्सी रोमानोव

क्या एक initializer_listपुनरावर्ती लेने के लिए एक समारोह बनाना संभव है ?
इडक्लेव ४६३०३५18१

33

एक सी ++ 17 समाधान: पूर्ण प्रकार की सुरक्षा + अच्छा कॉलिंग सिंटैक्स

चूंकि C ++ 11 में वेरिएडिक टेम्प्लेट्स की शुरुआत और C ++ 17 में फोल्ड एक्सप्रेशंस, एक टेम्प्लेट-फंक्शन को परिभाषित करना संभव है, जो कॉलर साइट पर कॉल करने योग्य है, जैसे कि यह एक वैरिएड फ़ंक्शन था, लेकिन फायदे के साथ :

  • दृढ़ता से सुरक्षित रहें;
  • तर्क की संख्या की रन-टाइम जानकारी के बिना, या "स्टॉप" तर्क के उपयोग के बिना काम करें।

यहाँ मिश्रित तर्क प्रकारों के लिए एक उदाहरण है

template<class... Args>
void print(Args... args)
{
    (std::cout << ... << args) << "\n";
}
print(1, ':', " Hello", ',', " ", "World!");

और सभी तर्कों के लिए लागू प्रकार मैच के साथ एक और:

#include <type_traits> // enable_if, conjuction

template<class Head, class... Tail>
using are_same = std::conjunction<std::is_same<Head, Tail>...>;

template<class Head, class... Tail, class = std::enable_if_t<are_same<Head, Tail...>::value, void>>
void print_same_type(Head head, Tail... tail)
{
    std::cout << head;
    (std::cout << ... << tail) << "\n";
}
print_same_type("2: ", "Hello, ", "World!");   // OK
print_same_type(3, ": ", "Hello, ", "World!"); // no matching function for call to 'print_same_type(int, const char [3], const char [8], const char [7])'
                                               // print_same_type(3, ": ", "Hello, ", "World!");
                                                                                              ^

अधिक जानकारी:

  1. वैरेडिक टेम्प्लेट, जिसे पैरामीटर पैक पैरामीटर पैक (C ++ 11 के बाद से) के रूप में भी जाना जाता है - cppreference.com
  2. गुना अभिव्यक्ति गुना अभिव्यक्ति (C ++ 17 के बाद से) - cppreference.com
  3. कोलीरू पर एक पूरा कार्यक्रम प्रदर्शन देखें ।

13
एक दिन बीमार आशा है कि मैं पढ़ सकता हूंtemplate<class Head, class... Tail, class = std::enable_if_t<are_same<Head, Tail...>::value, void>>
एलडियन

1
@ एडलियन ने इसे "यह बात तभी सक्षम की जाती है जब Headऔर " Tail... एक ही हो ", जहाँ" समान "का अर्थ होता है std::conjunction<std::is_same<Head, Tail>...>। इस अंतिम निश्चित को पढ़ें " Headजैसा कि सभी के लिए समान है Tail..."।
YSC

24

c ++ 11 में आप कर सकते हैं:

void foo(const std::list<std::string> & myArguments) {
   //do whatever you want, with all the convenience of lists
}

foo({"arg1","arg2"});

सूची आरम्भिक FTW!


19

C ++ 11 में वेरिएबल लॉजिक टेम्प्लेट करने का एक तरीका है जो वेरिएबल लॉजिक फंक्शन्स के लिए एक बहुत ही सुंदर और टाइप सेफ तरीका है। Bjarne खुद C ++ 11FAQ में वेरिएबल लॉजिक टेम्प्लेट का उपयोग करके प्रिंटफ का एक अच्छा उदाहरण देता है

व्यक्तिगत रूप से, मैं इसे इतना सुरुचिपूर्ण मानता हूं कि मैं C ++ में एक चर तर्क फ़ंक्शन के साथ भी परेशान नहीं करूंगा, जब तक कि संकलक को C ++ 11 चर तर्क टेम्पलेट के लिए समर्थन न हो।


@donlan - यदि आप C ++ 17 का उपयोग कर रहे हैं, तो आप कुछ मामलों में चीजों को बहुत सरल बनाने के लिए फोल्ड एक्सप्रेशन का उपयोग कर सकते हैं (यहां रचनात्मक रूप से सोचें, तो आप ,ऑपरेटर को फोल्ड एक्सप्रेशंस के साथ उपयोग कर सकते हैं )। अन्यथा, मुझे ऐसा नहीं लगता।
सर्वव्यापी

15

C ++ में C- स्टाइल वैरेडिक फ़ंक्शन समर्थित हैं।

हालाँकि, अधिकांश C ++ पुस्तकालयों में एक वैकल्पिक मुहावरे का उपयोग किया जाता है, जबकि 'c' printfफ़ंक्शन परिवर्तनशील तर्क लेता है, c++ coutऑब्जेक्ट <<ओवरलोडिंग का उपयोग करता है जो कि प्रकार की सुरक्षा और ADTs (शायद कार्यान्वयन सादगी की कीमत पर) को संबोधित करता है ।


इसके अलावा, यह केवल मुद्रण जैसे किसी फ़ंक्शन के मामले में काम करता है, जहां आपके पास वास्तव में प्रत्येक arg में एकल तर्क फ़ंक्शन का पुनरावृत्ति है। अन्यथा, आप केवल एक सूची को आरम्भ कर रहे हैं और सूची को चारों ओर के अंत के लिए पास कर रहे हैं std::initializer_lists... और यह पहले से ही एक सरल कार्य पर बड़े पैमाने पर जटिलता का परिचय दे रहा है।
क्रिस्टोफर

13

वररग्स या ओवरलोडिंग के अलावा, आप अपने तर्कों को एक std :: वेक्टर या अन्य कंटेनरों (std :: map for example) में एकत्र करने पर विचार कर सकते हैं। कुछ इस तरह:

template <typename T> void f(std::vector<T> const&);
std::vector<int> my_args;
my_args.push_back(1);
my_args.push_back(2);
f(my_args);

इस तरह से आपको टाइप सेफ्टी मिलेगी और इन वैरिएड तर्कों का तार्किक अर्थ स्पष्ट होगा।

निश्चित रूप से इस दृष्टिकोण में प्रदर्शन के मुद्दे हो सकते हैं लेकिन आपको उनके बारे में चिंता नहीं करनी चाहिए जब तक कि आप सुनिश्चित नहीं हैं कि आप कीमत का भुगतान नहीं कर सकते हैं। यह सी + + के लिए आ "Pythonic" दृष्टिकोण का एक प्रकार है ...


6
क्लीनर वैक्टर लागू नहीं करना होगा। इसके बजाय STL- स्टाइल संग्रह को निर्दिष्ट करने वाले टेम्पलेट तर्क का उपयोग करें, फिर तर्क के आरंभ और अंत के तरीकों का उपयोग करके इसके माध्यम से पुनरावृत्त करें। इस तरह आप std :: वेक्टर <T>, c ++ 11 का std :: array <T, N>, std :: initializer_list <T> का उपयोग कर सकते हैं या अपना खुद का संग्रह भी बना सकते हैं।
जेन्स Jकेब्लम

3
@ Jens thekerblom मैं सहमत हूं लेकिन इस तरह का विकल्प है कि इंजीनियरिंग से बचने के लिए, हाथ में समस्या के लिए विश्लेषण किया जाना चाहिए। चूंकि यह एपीआई हस्ताक्षर का मामला है, इसलिए अधिकतम लचीलापन और आशय / प्रयोज्य / मुख्यता आदि की स्पष्टता के बीच ट्रेडऑफ को समझना महत्वपूर्ण है
फ्रांसेस्को

8

एकमात्र तरीका सी शैली चर तर्कों के उपयोग के माध्यम से है, जैसा कि यहां वर्णित है । ध्यान दें कि यह एक अनुशंसित अभ्यास नहीं है, क्योंकि यह टाइपसाफ़ और त्रुटि-प्रवण नहीं है।


त्रुटि प्रवण द्वारा मुझे लगता है कि आप संभावित रूप से बहुत खतरनाक हैं? खासतौर पर अविश्वासित इनपुट के साथ काम करते समय।
केविन लोनी

हां, लेकिन सुरक्षा मुद्दों के प्रकार के कारण। उन सभी संभावित मुद्दों के बारे में सोचें जो नियमित रूप से प्रिंटफ के पास हैं: प्रारूपित तार पास किए गए तर्कों का मिलान नहीं करते हैं, और ऐसे। Printf एक ही तकनीक का उपयोग करता है, BTW।
डेव वान डेन आईंडी

7

सी-स्टाइल वैरगेज़ का सहारा लिए बिना ऐसा करने का कोई मानक C ++ तरीका नहीं है (... ) का ।

कुछ डिफ़ॉल्ट तर्क हैं जो संदर्भ के आधार पर "लुक" की तरह होते हैं, जैसे चर संख्या के तर्क:

void myfunc( int i = 0, int j = 1, int k = 2 );

// other code...

myfunc();
myfunc( 2 );
myfunc( 2, 1 );
myfunc( 2, 1, 0 );

सभी चार फ़ंक्शन कॉल myfuncअलग-अलग तर्कों के साथ कॉल करते हैं। यदि कोई नहीं दिया जाता है, तो डिफ़ॉल्ट तर्क का उपयोग किया जाता है। हालाँकि, ध्यान दें कि आप केवल अनुगामी तर्कों को छोड़ सकते हैं। कोई रास्ता नहीं है, उदाहरण के लिए iकेवल छोड़ देना और देना है j


4

यह संभव है कि आप ओवरलोडिंग या डिफ़ॉल्ट पैरामीटर चाहते हैं - डिफ़ॉल्ट फ़ंक्शन के साथ एक ही फ़ंक्शन को परिभाषित करें:

void doStuff( int a, double termstator = 1.0, bool useFlag = true )
{
   // stuff
}

void doStuff( double std_termstator )
{
   // assume the user always wants '1' for the a param
   return doStuff( 1, std_termstator );
}

यह आपको चार अलग-अलग कॉलों में से एक के साथ विधि को कॉल करने की अनुमति देगा:

doStuff( 1 );
doStuff( 2, 2.5 );
doStuff( 1, 1.0, false );
doStuff( 6.72 );

... या आप सी से कन्वेंशन बुला रहे v_args की तलाश में हो सकते हैं।


2

यदि आप जानते हैं कि प्रदान किए जाने वाले तर्कों की संख्या कितनी होगी, तो आप हमेशा कुछ फ़ंक्शन का उपयोग कर सकते हैं, जैसे ओवरलोडिंग

f(int a)
    {int res=a; return res;}
f(int a, int b)
    {int res=a+b; return res;}

और इसी तरह...


2

वैरिएबल टेम्प्लेट का उपयोग करना, उदाहरण के लिए console.logजावास्क्रिप्ट में देखा गया है:

Console console;
console.log("bunch", "of", "arguments");
console.warn("or some numbers:", 1, 2, 3);
console.error("just a prank", "bro");

फ़ाइल नाम जैसे js_console.h:

#include <iostream>
#include <utility>

class Console {
protected:
    template <typename T>
    void log_argument(T t) {
        std::cout << t << " ";
    }
public:
    template <typename... Args>
    void log(Args&&... args) {
        int dummy[] = { 0, ((void) log_argument(std::forward<Args>(args)),0)... };
        cout << endl;
    }

    template <typename... Args>
    void warn(Args&&... args) {
        cout << "WARNING: ";
        int dummy[] = { 0, ((void) log_argument(std::forward<Args>(args)),0)... };
        cout << endl;
    }

    template <typename... Args>
    void error(Args&&... args) {
        cout << "ERROR: ";
        int dummy[] = { 0, ((void) log_argument(std::forward<Args>(args)),0)... };
        cout << endl;
    }
};

1

जैसा कि अन्य लोगों ने कहा है, सी-स्टाइल वैरग। लेकिन आप डिफॉल्ट तर्कों के साथ भी कुछ ऐसा कर सकते हैं।


क्या आप विस्तृत कर सकते हैं?
निधि मोनिका का मुकदमा

@QPaysTaxes: डिफ़ॉल्ट तर्कों के साथ इसे कैसे किया जाए, उदाहरण के लिए, ज़ोल्टन के उत्तर को देखें।
थॉमस पैडरॉन-मैकार्थी

0

अब यह संभव है ... किसी भी और टेम्पलेट्स को बढ़ावा देने का उपयोग करते हुए इस मामले में, तर्क प्रकार मिश्रित हो सकते हैं

#include <boost/any.hpp>
#include <iostream>

#include <vector>
using boost::any_cast;

template <typename T, typename... Types> 
void Alert(T var1,Types... var2) 
{ 

    std::vector<boost::any> a(  {var1,var2...});

    for (int i = 0; i < a.size();i++)
    {

    if (a[i].type() == typeid(int))
    {
        std::cout << "int "  << boost::any_cast<int> (a[i]) << std::endl;
    }
    if (a[i].type() == typeid(double))
    {
        std::cout << "double "  << boost::any_cast<double> (a[i]) << std::endl;
    }
    if (a[i].type() == typeid(const char*))
    {
        std::cout << "char* " << boost::any_cast<const char*> (a[i]) <<std::endl;
    }
    // etc
    }

} 


void main()
{
    Alert("something",0,0,0.3);
}

0

सी और सी ++ समाधानों को शब्दार्थ सरलतम, निष्पादक और सबसे गतिशील विकल्प के लिए मिलाएं। यदि आप पेंच करते हैं, तो कुछ और प्रयास करें।

// spawn: allocate and initialize (a simple function)
template<typename T>
T * spawn(size_t n, ...){
  T * arr = new T[n];
  va_list ap;
  va_start(ap, n);
  for (size_t i = 0; i < n; i++)
    T[i] = va_arg(ap,T);
  return arr;
}

उपयोगकर्ता लिखते हैं:

auto arr = spawn<float> (3, 0.1,0.2,0.3);

शब्दार्थ, यह दिखता है और बिल्कुल एक एन-तर्क फ़ंक्शन की तरह लगता है। हुड के तहत, आप इसे एक या दूसरे तरीके से अनपैक कर सकते हैं।


-1

यदि सभी तर्कों और एक ही प्रकार के हैं, तो हम एक initial__list का उपयोग भी कर सकते हैं


-2
int fun(int n_args, ...) {
   int *p = &n_args; 
   int s = sizeof(int);
   p += s + s - 1;
   for(int i = 0; i < n_args; i++) {
     printf("A1 %d!\n", *p);
     p += 2;
   }
}

सादा संस्करण


1
और अपरिभाषित व्यवहार जो x86 के अलावा किसी अन्य चीज पर काम नहीं करेगा।
एसएस ऐनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.