2015-11-23 35 views
8
#include <iostream> 
using namespace std; 
int print(int i) 
{ 
    cout<<endl<<i; 
} 


template<typename ...Args> 
inline void pass(Args&&...args) 
{ 

} 

template<typename ...args> 
inline void expand(args&&... a) 
{ 
    print(a) ...; //this doesn't expand 
    //pass(print(a)...); this works 

} 
int main() { 



    expand(1,2,3,4); 

    return 0; 
} 

यह फेंकता त्रुटि:पैरामीटर के साथ विस्तार नहीं पैक '...'

In function 'void expand(args&& ...)': 
error: expected ';' before '...' token 
    print(a) ...; 
     ^
parameter packs not expanded with '...': 
    print(a) ...; 
      ^

क्यों इस "पास" समारोह के उपयोग के लिए आवश्यक है है?

+2

पैरामीटर पैक विस्तार मूल रूप से जहां एक अल्पविराम से अलग किए अनुमति दी है की अनुमति है। संदर्भों की एक निश्चित संख्या है: फ़ंक्शन पैरामीटर सूचियां, टेम्पलेट पैरामीटर सूचियां, प्रारंभकर्ता आदि। एक अभिव्यक्ति मान्य संदर्भ नहीं है। एक अल्पविराम ऑपरेटर अल्पविराम से अलग सूची नहीं बनाता है। –

+0

यदि एसओ आपको अधिक जानकारी जोड़ने के लिए कहता है, तो अधिक जानकारी जोड़ें। डमी पाठ नहीं। धन्यवाद। –

उत्तर

12

अनिवार्य रूप से, एक पैरामीटर पैक E... का विस्तार एक सूचीE1, E2, [...], EN, एक E पैदा करता है पैक में प्रत्येक तत्व के लिए। यह वाक्य रचनात्मक निर्माण केवल उन स्थानों पर मान्य है जहां सूचियां व्याकरणिक रूप से सही हैं, जैसे फ़ंक्शन कॉल, प्रारंभकर्ता सूचियां इत्यादि। एकाधिक अल्पविराम ऑपरेटरों वाली एक अभिव्यक्ति की गणना नहीं होती है।

मुझे विश्वास है कि fold expressions (N4295: Folding expressions (Andrew Sutton, Richard Smith)) के साथ आप बस लिखने के लिए सक्षम हो जाएगा:

(print(a), ...); 

इस अभिव्यक्ति में,

  • print(a) एक अविस्तारित पैरामीटर पैक के साथ एक अभिव्यक्ति है,
  • , ऑपरेटर है और
  • ... देसी सही गुना विस्तार gnates।

पूरे अभिव्यक्ति का परिणाम है कि (print(a), ...) केवल पैक विस्तार संदर्भों में भी हो सकता है

print(a1) , (print(a2), (print(a3), print(a4))) // (assuming four elements). 
+1

अब आपने मुझे आश्चर्यचकित कर दिया है कि यह मामला क्यों है, क्योंकि 'foo(), foo(); 'मान्य अभिव्यक्ति है। –

+0

@RichardHodges यह एक वैध अभिव्यक्ति है, लेकिन यह व्याकरण के अनुसार * सूची * नहीं है। – TartanLlama

+1

मैं समझता हूं कि। मैं क्या सोच रहा हूं कि पैक विस्तार सूचियों तक सीमित क्यों था और बयानों के लिए अनुमति नहीं थी। –

5

पैक विस्तार के रूप में तब्दील हो जाएगा। ये मूलतः हैं:

  • प्रारंभ
  • प्रारंभकर्ता सूचियों
  • कुल initializations
  • समारोह
  • सरणी initializations
इनमें से

आसान अपने मामले में उपयोग करने के लिए किया जाएगा कॉल braced अंतिम:

#include <iostream> 
using namespace std; 
int print(int i) 
{ 
    cout<<endl<<i; 
    return 0; 
} 

template<typename ...args> 
inline void expand(args&&... a) 
{ 
    using expander = int[]; 
    (void)expander{0, ((void)print(a), 0)...}; 
} 

int main() 
{ 
    expand(1,2,3,4); 

    return 0; 
} 

Demo

+0

@LightnessRacesinOrbit मुझे यह नहीं मिला –

+3

मैं सी ++ पर हँस रहा हूं। यह वाक्यविन्यास यह आसान काम करने का "सबसे आसान" तरीका है हंसने योग्य है। –

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