获得最大的类型

时间:2011-06-19 15:15:41

标签: c++ metaprogramming

如何在编译器中获取最大可用类型的名称?有可能吗?
类似的东西:

auto largest = get_largest_type();  
在我的情况下,

和auto会很长。

5 个答案:

答案 0 :(得分:4)

嗯,根据你需要的程度,你可以尝试一些严肃的元编程......

首先,您显然需要某种“pack”来定义所有可用的基元类型,所以这里是:

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;

然后你需要一种方法来根据大小对这些类型进行排序,所以首先,让我们定义一个能够为大小实现严格的弱排序的元函数:

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机器中输出,其中long double是最大的可用简单基本类型:

MATCH!

答案 1 :(得分:2)

不,这是不可能的。但是,您几乎可以保证64位是最大的类型 - 我不知道任何提供128位的编译器。如果做不到这一点,请让您的用户将其作为模板参数传递或使用特定于编译器的定义来生成typedef。

答案 2 :(得分:2)

仅对于整数类型,您可以使用<cstdint>标题,以便执行以下操作:

std::intmax_t largest;

我不知道任何包含浮点类型的功能。

答案 3 :(得分:0)

我想你可以编写一个重新处理主程序的小程序。 小程序可以使用sizeof()来比较所有数字类型以确定最大值。然后将主程序中的符号“LARGEST”替换为实际上最大的类型。

答案 4 :(得分:0)

您可以使用std::numeric_limits模板类来获取有关具有特化的基本类型的一些信息。

在某些编译器上,long double不大于long long,但在其他编译器上,long double的大小为double(MSVC)。