मैं के साथ चारों ओर खेल रहा था auto
में std::pair
। नीचे दिए गए कोड में, फ़ंक्शन f
को std::pair
उन प्रकारों को वापस करना है जो टेम्पलेट पैरामीटर पर निर्भर करते हैं।
एक कार्य उदाहरण:
उदाहरण 1
template <unsigned S>
auto f()
{
if constexpr (S == 1)
return std::pair{1, 2}; // pair of ints
else if constexpr (S == 2)
return std::pair{1.0, 2.0}; // pair of doubles
else
return std::pair{0.0f, 0.0f}; // pair of floats
}
यह gcc 9.2, gcc 10.0, clang 9.0 और clang 10.0 के साथ काम करता है।
अगला, मैं std::pair
स्पष्टता कारणों से स्पष्ट रूप से रिटर्न प्रकार लिखना चाहता था :
उदाहरण २
template <unsigned S>
std::pair<auto, auto> f()
{
if constexpr (S == 1)
return {1, 2};
/* ... */
}
दोनों gcc 9.2 / 10.0 और clang 9.0 / 10.0 इसे संकलित करने में विफल रहे।
gcc 9.2
error: invalid use of 'auto'
error: template argument 1 is invalid // first argument (auto) of std::pair
error: template argument 2 is invalid // second argument (auto) of std::pair
error: cannot convert '<brace-enclosed initializer list>' to 'int' in return
अंतिम त्रुटि संदेश से, gcc 9.2 यह मानता है कि std::pair<auto, auto>
यह एक है int
। इसे कैसे समझाया जा सकता है?
gcc 10.0
error: returning initializer list
यह त्रुटि समझ में आती है, हालाँकि, मुझे उम्मीद है कि कंस्ट्रक्टर std::pair
को आमंत्रित किया जाएगा, या क्या ऐसा कुछ है जो मैं यहाँ याद कर रहा हूँ?
क्लैंग 9.0 और 10.0
'auto' not allowed in template argument
excess elements in scalar initializer
no matching function for call to 'f'
ठीक है, क्लैंग को इनमें से कोई पसंद नहीं है। दूसरी त्रुटि संदेश से, ऐसा लगता है कि क्लैंग का यह भी मानना है कि रिटर्न प्रकार है int
।
अंत में, जीसी 10.0 के साथ संकलित की गई त्रुटि को ठीक करने के लिए, मैंने std::pair
स्पष्ट रूप से लौटने का फैसला किया :
उदाहरण ३
template <unsigned S>
std::pair<auto, auto> f()
{
if constexpr (S == 1)
return std::pair{1, 2};
/* ... */
}
क्लैंग 9.0 और 10.0
पहले जैसा ही, लेकिन एक अतिरिक्त के साथ:
no viable conversion from returned value of type 'std::pair<int, int>' to function return type 'int'
यहाँ क्लैंग को अभी भी लगता है कि हम वापस लौट रहे हैं int
?
gcc 9.2
पहले की तरह।
gcc 10.0
यह काम करता हैं!
मुझे लगता है कि कुछ सुविधाओं को अभी भी लागू किया जाना है, या ऊपर वर्णित स्थितियों में से एक में, क्या एक संकलक है जो सही है और दूसरा गलत है? मेरी राय में, उदाहरण 2 को काम करना चाहिए। या नहीं करना चाहिए?