2013-05-31 7 views
10

वर्दी प्रारंभ वाक्य रचना अंतर

A a{ A() }; 

और कर में क्या अंतर है,

A a(A{}); 

Most Vexing Parse से बचने के लिए? मुझे किसी विशेष का उपयोग कब करना चाहिए?

+2

इस विशेष स्थिति में, सबसे सरल विकल्प 'ए' होगा, है ना? अगर मैं इसे गलत समझ नहीं पा रहा हूं, तो आपके द्वारा सुझाए गए वाक्यविन्यास में केवल तभी अर्थ होता है जब अस्थायी आप 'ए' के ​​निर्माता को पास करना चाहते हैं, 'ए' से भिन्न प्रकार का है, सही? अर्थात। 'ए ए {बी()};'। – jogojapan

उत्तर

13

दो वाक्यविन्यास अधिकांश स्थितियों में समकक्ष हैं, और कौन सा चयन करना ज्यादातर स्वाद का विषय है। आप वर्दी प्रारंभ में कर रहे हैं, मैं कर रहा सुझाव है: अन्यथा

A a{ A{} }; 

, अकेले को स्पष्ट करने के लिए इस्तेमाल किया जा सकता कोष्ठकों:

A a((A())); // This can't be parsed as a function declaration 

सूचना, एक स्थिति (बहुत संभावना नहीं है कि वहाँ, मुझे कहना पड़ेगा) जहां आपके प्रश्न में दिखाए गए दो रूप बराबर नहीं हैं। अपनी कक्षा A एक निर्माता है कि एक initializer_list<A> लेता है, तो यह है कि निर्माता प्रतिलिपि निर्माता से अधिक इष्ट किया जाएगा जब ब्रेसिज़ उपयोग किया जाता है:

#include <initializer_list> 
#include <iostream> 

struct A 
{ 
    A() { } 
    A(std::initializer_list<A> l) { std::cout << "init-list" << std::endl; } 
    A(A const& a) { std::cout << "copy-ctor" << std::endl; } 
}; 

int main() 
{ 
    A a(A{}); // Prints "copy-ctor" (or nothing, if copy elision is performed) 
    A b{A()}; // Prints "init-list" 
} 

ऊपर अंतर इस live example में दिखाया गया है।

+2

असल में, पहला * मेरे लिए "कॉपी-सीटीओआर" प्रिंट नहीं करता है। मुझे लगता है कि इसकी प्रतिलिपि है। –

+0

@MemyselfandI: हू, ठीक है, संकलक प्रतिलिपि बना रहा है - लेकिन अवधारणात्मक रूप से, कॉपी कन्स्ट्रक्टर –

+0

चुना जाता है क्या प्रतिलिपि केवल तभी होती है जब ऑप्टिमाइज़ेशन सक्षम होते हैं? –

9

ज्यादातर स्थितियों में वे समकक्ष हैं, लेकिन A a{ A() };std::initializer_list कन्स्ट्रक्टर पसंद करेंगे यदि कोई मौजूद है, जबकि A a(A{}); एक चाल/प्रतिलिपि निर्माता को पसंद करेगा।

जब निर्माण एक चाल/प्रतिलिपि निर्माता को बुलाता है, तो नई वस्तु का निर्माण elided किया जा सकता है, लेकिन std::initializer_list कन्स्ट्रक्टर के लिए यह संभव नहीं है।

न तो वाक्यविन्यास को फ़ंक्शन घोषणा के रूप में कभी भी पार्स किया जाएगा, इसलिए दोनों सबसे अधिक परेशानी-पार्स से बचें।

#include <iostream> 
#include <initializer_list> 
struct A { 
    A() { 
     std::cout << "A()\n"; 
    } 
    A(A&&) { 
     std::cout << "A(A&&)\n"; 
    } 
    A(std::initializer_list<A>) { 
     std::cout << "A(std::initializer_list<A>)\n"; 
    } 
}; 
int main() 
{ 
    {A a{ A() };} // Prints "A()\n" "A(std::initializer_list<A>)\n" 
    {A a(A{});} // Prints "A()\n" and *possibly* 
        // (depending on copy elision) "A(A&&)\n" 
} 
संबंधित मुद्दे