2017-08-23 19 views
20

निम्नलिखित कोड को देखते हुए:अलग परिणाम जब एसटीडी कास्टिंग :: वैकल्पिक <T>

#include <iostream> 
#include <optional> 

struct foo 
{ 
    explicit operator std::optional<int>() { 
     return std::optional<int>(1); 
    } 
    explicit operator int() { 
     return 0; 
    } 
}; 

int main() 
{ 
    foo my_foo; 
    std::optional<int> my_opt(my_foo); 
    std::cout << "value: " << my_opt.value() << std::endl; 
} 

gcc 7.2.0 writesvalue: 1

एमएसवीसी 2017 (15.3) और clang 4.0.0 however writevalue: 0

सी ++ मानक के अनुसार कौन सा सही है?

उत्तर

18

चूंकि यह प्रत्यक्ष-प्रारंभिक है, हम enumerate the constructors और बस सबसे अच्छा चुनें। std::optional के लिए प्रासंगिक निर्माता ये हैं:

constexpr optional(const optional& other); // (2) 
constexpr optional(optional&& other) noexcept(/* see below */); // (3) 

template < class U = value_type > 
/* EXPLICIT */ constexpr optional(U&& value); // (8), with U = foo& 

दोनों कर रहे हैं व्यवहार्य ((8) केवल अधिभार संकल्प में भाग लेता है, तो intfoo& से constructible है और foostd::in_place_t है और न ही std::optional<int>, जो सभी के पकड़ है), लेकिन (8) सटीक मेल है जबकि (2) और (3) को उपयोगकर्ता द्वारा परिभाषित रूपांतरण की आवश्यकता होती है, इसलिए इसे प्राथमिकता दी जानी चाहिए। जीसीसी यहाँ गलत है।

हालांकि, जीसीसी वास्तव में (3) को भी नहीं बुलाता है। my_foo को optional<int> में कनवर्ट करने के परिणामस्वरूप यह सीधे my_opt प्रारंभ करता है। जीसीसी 7.2 प्रिंट 3 लेकिन 1a में से कोई भी, 1b, या 2 साथ इस कार्यक्रम:

मुझे लगता है कि एक स्वीकार्य रास्ता है नहीं लगता। मैंने 81952 दायर किया।

+0

मैंने हमेशा सोचा कि ओवरलोड रिज़ॉल्यूशन गैर-टेम्पलेट पसंद करता है। यह यहाँ अलग क्यों है? – Rakete1111

+6

@ Rakete1111 यह अलग नहीं है। ओवरलोड रिज़ॉल्यूशन "हमेशा" गैर-टेम्पलेट्स को पसंद नहीं करता है। समकक्ष रूपांतरण अनुक्रम रैंकिंग वाले दो उम्मीदवारों को देखते हुए, टाईब्रेकर्स में से एक गैर-टेम्पलेट को प्राथमिकता देना है। लेकिन हमारे पास समकक्ष रूपांतरण अनुक्रम रैंकिंग नहीं है। – Barry

+0

@Barry क्या हमारे पास समान रैंकिंग के साथ दो रूपांतरण नहीं हैं? एक 'int', जो (8) और एक 'वैकल्पिक ' के लिए ले जाएगा, जो (2) ले जाएगा? – Rakete1111

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