क्या एक तर्क बनाने वाले के पास कई तर्क होते explicit
हैं (कोई उपयोगी) प्रभाव होता है?
उदाहरण:
class A {
public:
explicit A( int b, int c ); // does explicit have any (useful) effect?
};
जवाबों:
C ++ 11 तक, हाँ, explicit
मल्टी-आर्ग कंस्ट्रक्टर पर उपयोग करने का कोई कारण नहीं ।
प्रारंभिक सूचियों के कारण C ++ 11 में परिवर्तन होता है। मूल रूप से, प्रारंभिक-सूची के साथ प्रतिलिपि-आरंभ (लेकिन प्रत्यक्ष प्रारंभ नहीं) के लिए आवश्यक है कि निर्माणकर्ता को चिह्नित नहीं किया जाए explicit
।
उदाहरण:
struct Foo { Foo(int, int); };
struct Bar { explicit Bar(int, int); };
Foo f1(1, 1); // ok
Foo f2 {1, 1}; // ok
Foo f3 = {1, 1}; // ok
Bar b1(1, 1); // ok
Bar b2 {1, 1}; // ok
Bar b3 = {1, 1}; // NOT OKAY
explicit
। मैं व्यक्तिगत रूप से मल्टी-आर्ग कंस्ट्रक्टर बनाने से परेशान नहीं होता explicit
।
आप इसे ब्रेस इनिशियलाइज़ेशन के लिए ठोकर देंगे (उदाहरण के लिए सरणियों में)
struct A {
explicit A( int b, int c ) {}
};
struct B {
B( int b, int c ) {}
};
int main() {
B b[] = {{1,2}, {3,5}}; // OK
A a1[] = {A{1,2}, A{3,4}}; // OK
A a2[] = {{1,2}, {3,4}}; // Error
return 0;
}
@StoryTeller और @ स्नेफ्टेल द्वारा उत्कृष्ट उत्तर मुख्य कारण हैं। हालांकि, IMHO, यह समझ में आता है (कम से कम मैं इसे करता हूं), भविष्य के प्रमाण के हिस्से के रूप में बाद में कोड में परिवर्तन होता है। अपने उदाहरण पर विचार करें:
class A {
public:
explicit A( int b, int c );
};
इस कोड से सीधे लाभ नहीं होता है explicit
।
कुछ समय बाद, आप के लिए एक डिफ़ॉल्ट मान जोड़ने का निर्णय लेते हैं c
, इसलिए यह इस प्रकार है:
class A {
public:
A( int b, int c=0 );
};
ऐसा करते समय, आप c
पैरामीटर पर ध्यान केंद्रित कर रहे हैं - पूर्वव्यापी में, इसका डिफ़ॉल्ट मान होना चाहिए। जरूरी नहीं कि A
आप खुद ही इसका निर्माण करें। दुर्भाग्य से, यह परिवर्तन explicit
फिर से प्रासंगिक बनाता है ।
इसलिए, यह बताने के लिए कि एक ctor है explicit
, यह ऐसा करने के लिए भुगतान कर सकता है जब पहली विधि लिख रहा हो।
explicit
यह हमेशा के लिए है, और तकनीकी सहायता उस परिवर्तन के बारे में कॉल के साथ जल जाएगी और यह बताते हुए घंटों बिताएगी कि explicit
बस शोर था, और इसे हटाना हानिरहित है। व्यक्तिगत रूप से, मैं भविष्य की भविष्यवाणी करने में बहुत अच्छा नहीं हूँ; यह तय करना काफी कठिन है कि एक इंटरफ़ेस को अब कैसा दिखना चाहिए ।
यहाँ इस चर्चा के लिए मेरे पाँच सेंट हैं:
struct Foo {
Foo(int, double) {}
};
struct Bar {
explicit Bar(int, double) {}
};
void foo(const Foo&) {}
void bar(const Bar&) {}
int main(int argc, char * argv[]) {
foo({ 42, 42.42 }); // valid
bar({ 42, 42.42 }); // invalid
return 0;
}
जैसा कि आप आसानी से देख सकते हैं, फ़ंक्शन के explicit
साथ इनिशियलाइज़र सूची का उपयोग करने से रोकता है bar
क्योंकि निर्माता के struct Bar
रूप में घोषित किया गया है explicit
।