2011-06-19 17 views
7

मैं अपने कंपाइलर में सबसे बड़ा उपलब्ध प्रकार का नाम कैसे प्राप्त कर सकता हूं? क्या यह सभी के लिए संभव है?
कुछ की तरह:सबसे बड़ा प्रकार उपलब्ध हो रहा है

auto largest = get_largest_type(); 

और ऑटो मेरे मामले में लंबे समय से लंबा हो जाएगा।

+1

आपका मतलब सबसे बड़ा आदिम प्रकार है? 'Int [100000]' के बारे में क्या? यह एक बहुत बड़ा प्रकार है, क्या यह गिनती है?और, ज़ाहिर है, इसके लिए क्या है? – jalf

+0

@jalf yes, मेरा मतलब सबसे बड़ा आदिम प्रकार उपलब्ध था – smallB

उत्तर

4

ठीक है, कितनी बुरी तरह से आप इस जरूरत पर निर्भर करता है, तो आप कुछ गंभीर metaprograming यहाँ की कोशिश कर सकते हैं ...

सबसे पहले, आपको "पैक" सभी उपलब्ध आदिम प्रकार को परिभाषित करने के लिए किसी तरह की जरूरत स्पष्ट रूप से होगा, इसलिए यहां है :

template<typename... TYPES> 
class pack 
{}; 

typedef pack<float, double, long double, unsigned short, unsigned int, 
    unsigned long, unsigned long long, short, int, long, long long> primitive_types; 

तो फिर तुम आकार के संबंध में इस प्रकार सॉर्ट करने के लिए एक तरह से की आवश्यकता होगी, तो सबसे पहले, चलो एक metafunction आकार के लिए एक stric कमजोर आदेश लागू करने में सक्षम को परिभाषित:

template<typename L, typename R> 
class smaller 
{ 
    public: 
     static const bool value = sizeof(L) < sizeof(R); 
}; 

अब, सॉर्टिंग एल्गोरिदम। यहां मैंने मनमाने ढंग से मर्ज सॉर्ट चुना है, जिसके लिए 3 अन्य मेटाफंक्शन की आवश्यकता है: पैक को संयोजित करने के लिए पैककैट, ऑर्डर के अनुसार उन्हें विलय करने के लिए विलय करें, और 2 अन्य पैक में पैक तोड़ने के लिए हल करें।

template<typename, typename> 
class pack_cat; 

template<typename... L, typename... R> 
class pack_cat<pack<L...>, pack<R...>> 
{ 
    public: 
     typedef pack<L..., R...> type; 
}; 

template<template<typename, typename> class, typename, typename> 
class pack_merge; 

template<template<typename, typename> class MF, typename HL, typename... TL, typename HR, typename... TR> 
class pack_merge<MF, pack<HL, TL...>, pack<HR, TR...>> 
{ 
    public: 
     typedef typename std::conditional<MF<HR, HL>::value, 
       typename pack_cat<pack<HR>, typename pack_merge<MF, pack<HL, TL...>, pack<TR...>>::type>::type, 
       typename pack_cat<pack<HL>, typename pack_merge<MF, pack<TL...>, pack<HR, TR...>>::type>::type>::type type; 
}; 

template<template<typename, typename> class MF, typename H, typename... T> 
class pack_merge<MF, pack<H, T...>, pack<>> 
{ 
    public: 
     typedef pack<H, T...> type; 
}; 

template<template<typename, typename> class MF, typename... R> 
class pack_merge<MF, pack<>, pack<R...>> 
{ 
    public: 
     typedef pack<R...> type; 
}; 

template<typename> 
class halve; 

template<typename A, typename B, typename... T> 
class halve<pack<A, B, T...>> 
{ 
    public: 
     typedef typename pack_cat<pack<A>, typename halve<pack<T...>>::L>::type L; 
     typedef typename pack_cat<pack<B>, typename halve<pack<T...>>::R>::type R; 
}; 

template<typename T> 
class halve<pack<T>> 
{ 
    public: 
     typedef pack<T> L; 
     typedef pack<> R; 
}; 

template<> 
class halve<pack<>> 
{ 
    public: 
     typedef pack<> L; 
     typedef pack<> R; 
}; 

template<template<typename, typename> class MF, typename P> 
class pack_sort 
{ 
    private: 
     typedef typename halve<P>::L L; 
     typedef typename halve<P>::R R; 

    public: 
     typedef typename pack_merge<MF, typename pack_sort<MF, L>::type, typename pack_sort<MF, R>::type>::type type; 
}; 

template<template<typename, typename> class MF, typename H> 
class pack_sort<MF, pack<H>> 
{ 
    public: 
     typedef pack<H> type; 
}; 

template<template<typename, typename> class MF> 
class pack_sort<MF, pack<>> 
{ 
    public: 
     typedef pack<> type; 
}; 

अन्त में आप लागू करने के लिए एक पैकेट है, जो सीधा है की अंतिम तर्क पुन: प्राप्त करने के लिए एक metafunction की आवश्यकता होगी:

template<typename> 
class pack_get_last; 

template<typename H, typename... T> 
class pack_get_last<pack<H, T...>> 
{ 
    public: 
     typedef typename pack_get_last<pack<T...>>::type type; 

}; 

template<typename H> 
class pack_get_last<pack<H>> 
{ 
    public: 
     typedef H type; 
}; 

अब, एक परीक्षण कार्यक्रम आप को साबित करना है कि यह सब कबाड़ कोड मैंने लिखा वहाँ वास्तव में काम करता है:

0123: एक x64 Linux मशीन जीसीसी 4.6, जहां लंबे समय डबल सबसे बड़ा उपलब्ध सरल आदिम प्रकार है का उपयोग करने में

#include <iostream> 
#include <utility> 

/* all those metafunctions come here */ 

int main() 
{ 
    typename pack_get_last<typename pack_sort<smaller, primitive_types>::type>::type largest; 

    if(std::is_same<decltype(largest), long double>::value) 
     std::cout << "MATCH!\n"; 
} 

आउटपुट

MATCH! 
+0

यह कुछ है। धन्यवाद। – smallB

0

मुझे लगता है कि आप एक छोटा प्रोग्राम लिख सकते हैं जो आपके मुख्य कार्यक्रम को पुन: संसाधित करता है। छोटा प्रोग्राम सबसे बड़ा निर्धारित करने के लिए सभी संख्यात्मक प्रकारों की तुलना करने के लिए sizeof() का उपयोग कर सकता है। फिर आपके मुख्य कार्यक्रम में "सबसे बड़ा" प्रतीक को उस प्रकार के साथ बदल देगा जो वास्तव में सबसे बड़ा था।

0

आप प्राइमेटिव प्रकारों के बारे में कुछ जानकारी प्राप्त करने के लिए std::numeric_limits टेम्पलेट क्लास का उपयोग कर सकते हैं।

ऐसा नहीं है कि कुछ compilers पर एक long doublelong long से बड़ा हालांकि दूसरों पर एक long double एक double (MSVC) के आकार है।

2

नहीं, यह संभव नहीं है। हालांकि, आप काफी गारंटी दे सकते हैं कि 64 बिट सबसे बड़ा प्रकार है- मुझे किसी भी कंपाइलर की जानकारी नहीं है जो 128 बिट प्रदान करता है। विफल होने पर, अपने उपयोगकर्ता को इसे टेम्पलेट पैरामीटर के रूप में पास करने के लिए प्राप्त करें या टाइपिफ़ाफ़ बनाने के लिए कंपाइलर-विशिष्ट परिभाषाओं का उपयोग करें।

std::intmax_t largest; 

मैं किसी भी ऐसी कार्यक्षमता चल शामिल है कि प्रकार बताते हैं के बारे में पता नहीं कर रहा हूँ, हालांकि:

+0

[कम से कम एक है] (http://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html), हालांकि सभी लक्ष्यों पर नहीं। – Damon

+0

सिम-प्रकारों के बारे में क्या? – Simon

+0

कुछ मशीनों पर लंबे समय तक डबल बिट 128 बिट्स है। –

2

पूर्णांक प्रकार के लिए केवल, आप <cstdint> हैडर, जो आप करने की अनुमति देता का उपयोग कर सकते हैं।

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