2015-05-06 5 views
5

जब मैं std::common_typeवापसी प्रकार त्रिगुट के लिए आवेदन किया (? :) अभिव्यक्ति

template <class ...T> struct common_type; 

template <class T> 
struct common_type<T> { 
    typedef decay_t<T> type; 
}; 

template <class T, class U> 
struct common_type<T, U> { 
    typedef decay_t<decltype(true ? declval<T>() : declval<U>())> type; 
}; 

template <class T, class U, class... V> 
struct common_type<T, U, V...> { 
    typedef common_type_t<common_type_t<T, U>, V...> type; 
}; 

भाग दो टेम्पलेट तर्क के लिए एक आम प्रकार मुझे बनाता पाने के लिए की एक संभव कार्यान्वयन के लिए एक कोड का टुकड़ा पर गौर जब उलझन में। यह टर्नरी ऑपरेटर का उपयोग decltype के साथ है।

जैसा कि मुझे पता है कि दूसरे या तीसरे ऑपरेंड को वापस करना है, पहले ऑपरेंड के मूल्य से तय किया जाता है। इस स्निपेट में, पहला ऑपरेंड सच है जिसका अर्थ है कि अभिव्यक्ति का वापसी मूल्य हमेशा declval<T>() होगा। अगर ऐसा है मैं क्या सोचा था जिसका कोई मतलब ... इसलिए, मैं निम्नलिखित परीक्षण

int iii = 2; 
float fff = 3.3; 
std::cout << typeid(decltype(false? std::move(iii):std::move(fff))).name() << std::endl; 
std::cout << typeid(decltype(std::move(iii))).name() << std::endl; 
std::cout << typeid(decltype(false ? iii : fff)).name() << std::endl; 
std::cout << typeid(decltype(true ? iii : fff)).name() << std::endl; 

// [02:23:37][[email protected]++_test]$ g++ -std=c++14 -g common_type.cpp 
// output 
// f 
// i 
// f 
// f 

चल परिणाम, परिणाम क्या मैं हालांकि

int iii = 2; 
float fff = 3.3; 
std::cout << typeid(decltype(false ? iii : fff)).name() << std::endl; // should return f; 
std::cout << typeid(decltype(true ? iii : fff)).name() << std::endl; // should return i; 
इस प्रकार की तरह होना चाहिए के साथ तुलना की कोशिश की है

कोई भी जब यह समझाने में मदद कर सकता है कि क्यों चल रहा परिणाम अलग है?

दूसरे शब्दों में, जब यह एक टर्नरी अभिव्यक्ति पर लागू होता है तो decltype का रिटर्न परिणाम क्या होता है?

+4

आपके उदाहरण कोड में, 'iii' में मान को 'फ्लोट' प्रकार में परिवर्तित कर दिया गया है, क्योंकि टर्नरी का परिणाम" व्यापक "प्रकार है। – jxh

+0

मैंने सोचा कि अगर दूसरे और तीसरे ऑपरेंड एक ही प्रकार में नहीं हैं, तो निश्चित रूप से रूपांतरण नहीं होगा। क्योंकि ** (सत्य? 1: 2.0) ** 1.0 के बजाय 1 वापस आ जाएगा। @ टी.सी. के अद्भुत स्पष्टीकरण के अनुसार मुझे बिंदु मिल गया है। धन्यवाद औश्र सबकुछ वही है। – ryu

उत्तर

3

अभिव्यक्ति का प्रकार संकलन-समय संपत्ति है। एक सशर्त अभिव्यक्ति (और इसलिए चयनित शाखा) में पहले ऑपरेंड का मूल्य सामान्य रूप से रन-टाइम चीज़ है, इसलिए यह अभिव्यक्ति के प्रकार को संभवतः प्रभावित नहीं कर सकता है।

इसके बजाय, नियमों का एक जटिल सेट (मानक के एक पृष्ठ से अधिक, जिसमें से मैंने this answer में उद्धृत किया है) का निर्धारण यह निर्धारित करने के लिए किया जाता है कि दूसरे और तीसरे ऑपरेशंस का "सामान्य प्रकार" क्या है, और सशर्त अभिव्यक्ति है उस प्रकार का। std::common_type केवल मूल भाषा में मौजूदा नियमों को लेता है।

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