正在获取可用的最大类型

Getting the largest type available

本文关键字:类型 获取      更新时间:2023-10-16

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

auto largest = get_largest_type();  

在我的情况下,汽车将是漫长的。

好吧,根据你的迫切需要,你可以在这里尝试一些严肃的元编程。。。

首先,您显然需要某种"包"来定义所有可用的基元类型,因此它是:

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

现在,排序算法。在这里,我任意选择了merge sort,它需要另外3个元函数:pack_cat用于连接包,pack_merge用于根据顺序合并包,而halve用于在另外两个包中分解包。

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!

不,这是不可能的。然而,你可以保证64位是最大的类型——我不知道有任何编译器提供128位。否则,让用户将其作为模板参数传入,或者使用编译器特定的定义来生成typedef。

仅对于整数类型,您可以使用<cstdint>标头,它允许您执行:

std::intmax_t largest;

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

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

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

请注意,在某些编译器上,long double大于long long,而在其他编译器上long doubledouble(MSVC)的大小。