2015-11-20 28 views
10

में सी ++ 14:अभिन्न या गणना प्रकार के लिए टी टी {x} और टी टी = {x} के बीच अंतर?

किसी भी अभिन्न या गणना प्रकार T के लिए और किसी भी अभिव्यक्ति expr के लिए:

struct S { T t { expr }; }; 

और

struct S { T t = { expr }; }; 
:

वहाँ कभी के बीच एक अंतर है

अद्यतन:

मैं [dcl.init.list]p3b5 को मिला कहते हैं जो:

If the initializer list has a single element of type E and either T is not a reference type or its referenced type is reference-related to E, the object or reference is initialized from that element.

मेरा मानना ​​है कि इस उद्धरण दोनों डायरेक्ट-सूची-प्रारंभ और कॉपी-सूची-प्रारंभ पर लागू होता है।

तो मुझे लगता है कि जवाब नहीं है, कोई अंतर नहीं है।

+1

क्यों होगा ..? –

उत्तर

5

आप direct initialization और copy initialization संदर्भ पर एक नज़र डालें, तो आप एक ही शब्द मिलेगा:

if T is a non-class type, standard conversions are used, if necessary, to convert the value of other to the cv-unqualified version of T

तो वहाँ कोई अंतर नहीं होना चाहिए। इन initializations के अंतर केवल वर्ग प्रकार के लिए लागू होता है: प्रतिलिपि प्रारंभनहींexplicit निर्माणकर्ता और explicit उपयोगकर्ता परिभाषित रूपांतरण ऑपरेटरों, प्रत्यक्ष प्रारंभ करता है पर विचार करता है। इंटीग्रल और गणना प्रकारों में से कोई भी नहीं है।

संपादित करें:
@ᐅ Johannes Schaub - litb ᐊ answered a relative question to this one और (केवल कोष्ठक, ब्रेसिज़ के बजाय के बारे में) वह ऐसे ही समान शब्दों (जोर मेरा) के साथ 8.5/14 संदर्भित:

The form of initialization (using parentheses or =) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type; see below. If the entity being initialized does not have class type, the expression-list in a parenthesized initializer shall be a single expression.

मैं मानक में {} समकक्ष नहीं मिल सकता है, या तो। मुझे आशा है कि का समर्थन करने के लिए पर्याप्त तर्क हैं उत्तर में कोई अंतर नहीं है।

+0

आपका लिंक ब्रांड्स नहीं, ब्रांड्स के बारे में है। यह स्पष्ट नहीं है कि वही तर्क यहां हैं। –

+0

मैंने सोचा कि मेरे उत्तर का पहला भाग पर्याप्त था। मुझे अभी भी उम्मीद है कि '()' बनाम '=()' और '{}' बनाम '= {}' के बीच प्रभावों में एक स्थिरता है। – LogicStuff

+1

ठीक है, '{}' बनाम '= {}' उपयोगकर्ता अपेक्षाओं के अनुरूप है, न कि '()' बनाम '=()'; विचार करें: 'अस्थिर int x = 42; चार ए (चार (एक्स)); चार बी = (चार (एक्स)); चार सी {चार (एक्स)}; char d = {char {x}}; ' –

1
  1. struct S {T t { expr };}; एक गैर स्थिर डेटा सदस्य प्रारंभकर्ता कि बराबरी का उपयोग नहीं करता पर हस्ताक्षर है।
  2. struct S{T t = { expr };}; एक गैर-स्थैतिक डेटा सदस्य प्रारंभकर्ता है कि बराबर चिह्न का उपयोग करता है।

पहला मामला है, जबकि दूसरा एक कॉपी-सूची-प्रारंभ है एक डायरेक्ट-सूची-प्रारंभ है।

डायरेक्ट-सूची-प्रारंभ और कॉपी-सूची-प्रारंभ के बीच अंतर यह है कि पहले मामले के लिए दोनों स्पष्ट और गैर स्पष्ट कंस्ट्रक्टर्स, माना जाता है, जबकि दूसरे केवल गैर स्पष्ट के लिए रचनाकारों को बुलाया जा सकता है।

स्पष्ट करने के लिए, निम्न उदाहरण पर विचार करें:

struct Foo { 
    int i; 
    explicit Foo(int i_) : i(i_) {} 
}; 

struct Bar { 
    Foo f {1}; 
}; 

Live Demo

इस उदाहरण Foo में एक explicit निर्माता है और Bar प्रत्यक्ष अपने सदस्य प्रकार Foo की f initializes। उदाहरण कोड सीधे शुरू होने के बाद से संकलित करता है क्योंकि explicit और non-explicit दोनों रचनाकारों पर विचार किया जाता है।

अब हम गैर-स्थैतिक डेटा सदस्य प्रारंभकर्ता को बराबर चिह्न के उपयोग के साथ बदलने के द्वारा उदाहरण को बदलते हैं, जो गैर-स्थैतिक डेटा सदस्य प्रारंभकर्ता को समान-चिह्न के उपयोग के साथ प्रत्यक्ष-सूची-प्रारंभिकता का मामला है, कॉपी-सूची-प्रारंभिकरण का मामला है।

struct Foo { 
    int i; 
    explicit Foo(int i_) : i(i_) {} 
}; 

struct Bar { 
    Foo f = {1}; 
}; 

Live Demo

अब ऊपर के उदाहरण संकलन नहीं करता है और एक त्रुटि का उत्सर्जन करता है:

error: chosen constructor is explicit in copy-initialization

यह आशा की जाती है क्योंकि के रूप में पहले से ही कॉपी-सूची-आरंभीकरण केवल गैर स्पष्ट उल्लेख किया गया है रचनाकारों को बुलाया जा सकता है।

अब गणक और अन्य अभिन्न प्रकारों के लिए, ऊपर प्रदर्शित अंतर लागू नहीं होगा (यानी, कोई कन्स्ट्रक्टर शामिल नहीं है)। इस प्रकार, दो बयान (यानी, [1] और [2]) बराबर होंगे।

enum class Foo {A, B, C}; 

struct Bar { 
    Foo f{Foo::A}; 
}; 

और

enum class Foo {A, B, C}; 

struct Bar { 
    Foo f = {Foo::A}; 
}; 

दोनों उदाहरण ठीक संकलन:

लेकिन पूर्णता के लिए, निम्न उदाहरण पर विचार कर सकते हैं।

इसके अलावा निम्न उदाहरण पर विचार करें:

struct Bar { 
    int i {1}; 
}; 

और

struct Bar { 
    int i = {1}; 
}; 

दोनों उदाहरण भी ठीक संकलन।

+1

"ठीक से संकलित" और "साइड इफेक्ट्स में कोई अंतर नहीं" बराबर बयान नहीं हैं। – Orient

+0

संकलन ठीक है यह दर्शाता है कि प्रकार के लिए निर्मित अंतर के लिए लागू नहीं होता है। नतीजतन, प्रकार के निर्माण के लिए दुष्प्रभावों में कोई अंतर नहीं है। – 101010

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