2011-06-19 32 views
7

如何在編譯器中獲取最大可用類型的名稱?它有可能嗎?
喜歡的東西:獲取最大可用類型

auto largest = get_largest_type(); 

和經銷商在我的情況會很長很長。

+1

您是指最大的原始類型?那麼'int [100000]'呢?這是一個非常大的類型,這算不算?而且,當然,這是爲了什麼? – jalf

+0

@jalf是的,我的意思是最大的原始類型可用 – 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; 

然後你需要一種方法來此類型對於大小排序,所以,首先,讓我們確定能夠實現的大小一個STRIC弱順序一元函數:

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

現在,排序算法。在這裏,我任意選擇了合併排序,這需要3個其他元函數:pack_cat用於連接包,合併用於根據順序合併它們,並且在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; 
}; 

最後,你需要一個元函數用於檢索一包,這是直截了當的最後一個參數來實現:

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; 
}; 

現在,一個測試程序,以證明你是這一切的垃圾代碼我寫的在那裏實際工作:

#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"; 
} 

輸出在使用gcc 4.6,其中長雙是最大可用簡單的原始類型的x64 Linux機器:

MATCH! 
+0

這是什麼。謝謝。 – smallB

0

我想你可以寫一個小程序來重新處理你的主程序。 小程序可以使用sizeof()比較所有數字類型來確定最大值。然後,將主程序中的符號「LARGEST」替換爲實際最大的類型。

0

您可以使用std::numeric_limits模板類獲取有關具有特化的原始類型的一些信息。

這並不是說在某些編譯器一個long doublelong long較大雖然上他人long doubledouble(MSVC)的大小。

2

不,這是不可能的。但是,幾乎可以保證64位是最大的類型 - 我不知道任何提供128位的編譯器。如果不這樣做,請讓用戶將其作爲模板參數傳遞或使用編譯器特定的定義來進行typedef。

+0

[至少有一個](http://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html),但不是所有的目標。 – Damon

+0

SIMD類型怎麼樣? – Simon

+0

長雙倍在某些機器上是128位長。 –

2

對於整數類型而已,你可以使用<cstdint>頭,它可以讓你做:

std::intmax_t largest; 

我不知道有任何這樣的功能,包括浮點類型,雖然。